So I have a package with a function that uploads a file to Twilio:
const FD = require('form-data');
const axios = require('axios');
async function createFunctionResource(serviceUid, functionUid, client){
let collect_file = "Hello World"
let url = `https://serverless-upload.twilio.com/v1/Services/${serviceUid}/Functions/${functionUid}/Versions`
let form = new FD();
collect_file = "test"
form.append("Path", "collect");
form.append("Visibility", "public");
form.append("Content", collect_file, "collect.js");
form.append("contentType", "application/javascript");
await axios.post(url, form, {
headers: {
Authorization: 'Basic ' + Buffer.from(`${client.accountSid}:${client.password}`).toString('base64'),
...form.getHeaders(),
},
})
}
This works completely fine in node.js and it gets uploaded with the message "Hello World" in the file.
I'm trying to put this into an electron app so I preload this package in preload.js with nodeIntegration set to true but whenever I try to upload a file I get:
Request failed with status code 400
With the error response being:
{"message":"No file attached to request","code":70002,"user_error":true,"http_status_code":400,"params":{}}
Does preloading a package make it act exactly the same as it does in node.js?
Can u add cotent-type in headers section and check .
"content-type": "application/json"
Even though you may try and preload a package with axios hoping it runs in a node environment, requests are done under XHR (browser).
To fix this you must specify the adapter to be HTTP by adding adapter: require('axios/lib/adapters/http')
await axios.post(url, form, {
headers: {
Authorization: 'Basic ' + Buffer.from(`${client.accountSid}:${client.password}`).toString('base64'),
...form.getHeaders(),
},
adapter: require('axios/lib/adapters/http'),
})
}
Related
I have a problem with this error:
Access to XMLHttpRequest at 'https://...' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
POST https://... net::ERR_FAILED
I am trying to send data but getting a "CORS" error
Am I missing something?
Here is my code
var dataBlob = File;
const submit = async () => {
//Convert Blob URL to file object with axios
const config = { responseType: "blob" };
await axios.get(mediaBlobUrl, config).then((response) => {
dataBlob = new File([response.data], "record", { type: "media" });
});
let formdata = new FormData();
formdata.append("sequence", "L");
formdata.append("video", dataBlob);
console.log("data", dataBlob);
//POST
try {
console.log(formdata.getAll);
let result = await axios({
url: "https://abc...",
method: "POST",
data: formdata,
});
console.log(result.data);
} catch (err) {
console.log(err);
}
It's nothing unusual at all if you try to access 3rd party api providers from your development environment.
You can test a source a prior via:
curl -i -X OPTIONS source/of/your/desire/ping \\ -H 'Access-Control-Request-Method: GET' \\ -H 'Access-Control-Request-Headers: Content-Type, Accept' \\ -H 'Origin: <http://localhost:3000>'
If you'll get back the CORS message, you will need to provide a proxy for your local env.
For CRA (Create React App) apps
There is a quite easy way nowadays for apps that are based on CRA and if you only need to setup one proxy in development. You just need to provide the needed proxy in your package.json:
"proxy": "https://theThirdPartyResource",
See documentation: https://create-react-app.dev/docs/proxying-api-requests-in-development/
Manual way
To avoid CORS issues in your dev environment you can use a proxy provided by e.g. http-proxy-middleware (https://www.npmjs.com/package/http-proxy-middleware)
With it installed you can create a file named setupProxy.js in your /src directory like:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = (app) => {
app.use(
'/proxy',
createProxyMiddleware({
target: 'https://originalApi.com/api/v1',
changeOrigin: true,
pathRewrite: {
'/proxy': '/',
},
})
);
};
In your axios request, you will be able to use:
axios.get('/proxy/suburl', config)
.then((response) => {
// what ever you want to do with your response
}).catch(error => console.log(error))
I have created a Chrome extension that collects some data and sends a POST request to my server. The code sending this request is very simple:
var payload =
{
prop1: 'SomeValue',
prop2: 'SomeValue',
...
};
var requestSettings = {
method: 'POST',
headers: {
'Content-Type': ' application/json'
},
body: JSON.stringify(payload)
};
var webRequest = new Request("https://mysite.xyz/api/process", requestSettings);
var response = await fetch(webRequest);
It works fine most of the times, but some of my users complained that the extension was not working properly, so I asked them to create a HAR file to see what was wrong with the requests that the extension was sending.
After inspecting the HAR file I found out that my extension was sending an empty POST body ("bodySize": 0 in HAR), although the Content-Length request header was not zero, and this caused my API to return an error, and the extension couldn't continue its work. Any ideas why the request body can be empty, and how to fix it?
You need to use cors npm package in your server(api), and then just don't add mode: 'no-cors' in requestSettings coz many people did this mistake.
And Try to fetch data in chrome without using requests, just fetch directly.
Edit:these are some few things you need to do in your express based api,
api.js will look like this;
const app = require('express')();
const cors = require('cors');
app.use(cors())
app.use(express.json())
chrome-extension's script:
var payload =
{
prop1: 'SomeValue',
prop2: 'SomeValue',
...
};
var requestSettings = {
method: 'POST',
headers: {
'Content-Type': ' application/json'
},
body: JSON.stringify(payload)
};
var response = await fetch("https://mysite.xyz/api/process", requestSettings);
``
I have a client side javascript sdk that submits an image to a server side node.js api that uses the multer library to parse the image.
However ive noticed if i set a header to be content-type multipart-formdata multer will throw an error saying
Error: Multipart: Boundary not found
async submitDocument(id, side, image) {
const url = this.API_URL + "/api/document";
let formData = new FormData();
formData.set("image", image, "front.jpg");
formData.set("side", side);
let headers = new Headers();
headers.set("content-type", "multipart/form-data");
headers.set("Authorization", "Bearer " + this.API_KEY);
const request = {
method: "POST",
body: formData,
headers: headers,
};
try {
const response = await fetch(url, request);
const data = await response.json();
return data;
} catch (err) {
throw err;
}
}
As the error message says, a multipart/form-data content-type requires a boundary parameter.
Don't set the Content-Type yourself. Allow the browser to generate it from the formData object.
npm module connect-multiparty may helpful to you. From server-side node application.
server.js
const multipart = require('connect-multiparty');
const multipartMiddleware = multipart();
router.post('/api/document', multipartMiddleware);
router.post('/api/document', (req, res) => {
console.log(req.files)
})
post-man api test sample -
https://i.stack.imgur.com/vxBpz.png
I'm making a project using Node.js (8.9.4) and Express (4.16.2). Basically, with Node.js i'm consulting an external API and then with Express make a route to consume this result. My surprise was that when I used Axios library, it make my response to delay up to ~30s. I wanted to check if it was my problem or was from the API... I've checked it with PostMan and it returns in less than 300ms. Then I've thought it was any problem related with Axios, so I've decided to use request-promise but...again 30s. The last test I've made is using Node.js native 'https' util and...yes, less than 300ms again.
Anyone knows whats the problem with those packages? Am I condemned to use callbacks instead of promises?
Here's my base code... (AXIOS, Request-Promise... 30s delay in response)
const rp = require('request-promise);
const BASE_URL = 'my https url';
const AUTH_TOKEN = 'my auth token';
const options = {
uri: BASE_URL + '/my-route',
qs: { myQS: true },
headers: { authorization: AUTH_TOKEN }
method: 'GET'
};
rp(options)
.then(response => response)
.catch(error => error);
Here's my base code with HTTPS.... 300ms delay in response
const https = require('https');
const AUTH_TOKEN = 'my auth token';
const options = {
hostname: 'my hostname',
port: 443,
path: 'my path',
headers: { authorization: AUTH_TOKEN },
method: 'GET'
};
https.get(options, (res) => {
res.on('data', d => d);
};
Just a guess, but sounds like Axios is going via a different route in your network. Are both requests configured to use the same proxy setup?
I'm trying to use the HTML validator API. The curl examples work fine for me and I can run them find in Node as a child process. Here is the code for that:
var command = ('curl -H "Content-Type:text/html; charset=utf-8" --data-binary #' + file +
' https://validator.w3.org/nu/?out=json');
exec(command, function(err1, out, err2) {
console.log(out);
console.log('done');
});
However, when I tried to use a standard HTTP request, I couldn't get it working. I tried it with the Unirest library for Node. Here is the code I used:
var source = '<html><head><title>a</title></head><body>a</body></html>';
var url = 'http://validator.w3.org/nu/?out=json';
var Request = unirest.post(url);
Request.headers({'Content-Type': 'text/html', 'charset': 'utf-8'});
Request.send(source);
Request.end(res => console.log(res));
The response body is undefined and the response raw_body is empty. I don't know what I'm doing wrong and would appreciate any help.
Seems validator.w3.org won't respond to requests without a user-agent header. Add this header:
Request.headers({'Content-Type': 'text/html; charset=utf-8', 'user-agent': 'Node.js'});
Or use whatever useragent you want.
With super agent:
const request = require('superagent');
const body = '<html><head><title>a</title></head><body>a</body></html>';
request.post('https://validator.w3.org/nu/?out=json')
.set('Content-Type', 'text/html; charset=utf-8')
.send(body)
.end((err, res) => {
console.log('got body: ' + JSON.stringify(res.body));
});