const form_data = new FormData();
form_data.append("File", fs.createReadStream(pathToFile));
form_data.append('Login', alias.toUpperCase());
const request_config = {
headers: {
"Authorization": "Basic 123",
"Content-Type": 'multipart/form-data'
},
data: form_data
};
await axios.post(url, params, request_config).then(response => {
Posting to an endpoint I can't debug. The response is a 500.
This is the error:
Is this the correct way do it?
Can I somehow see exactly what Axios is sending?
This is a postman request I received from the author of the API. This passes:
POST /api/upload HTTP/1.1
Host: api.test.contoso.se
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Basic 123
User-Agent: PostmanRuntime/7.13.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 089af753-fa12-46c4-326f-dfc39c36faab,c5977145-ece3-4b53-93ff-057788eb0dcf
Host: api.test.contoso.se
accept-encoding: gzip, deflate
content-length: 18354
Connection: keep-alive
cache-control: no-cache
Content-Disposition: form-data; name="Lang"
SV
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="File"; filename="/C:/Users/file.docx
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="Login"
ABC
The error message in your screenshot is clear: "Missing content-type boundary".
To use axios for multipart/form-data request, you need to set boundary to upload the file. Example code is:
const form_data = new FormData();
...
const request_config = {
headers: {
"Authorization": "Basic 123",
"Content-Type": 'multipart/form-data; boundary=' + form._boundary
},
data: form_data
};
await axios.post(...)
"Can I somehow see exactly what Axios is sending?"
You can use HTTP proxy software such as Charles to intercept the request, and check what data is sent.
Related
I'm writing a REST API client that calls an API endpoint to obtain a PDF.
I'm using axios to consume the API:
const res = await axios({
method: 'GET',
url: url,
headers: {
'authorization': 'Bearer ' + at,
},
proxy: false,
httpsAgent: httpsAgent
});
console.log(res.data);
The response is of type multipart/form-data, in the following way:
content-type: multipart/form-data; boundary=95b77841-292d-4a0b-a689-787fcc0aa889
body:
--95b77841-292d-4a0b-a689-787fcc0aa889
Content-Disposition: form-data; name="metadata"
Content-Type: application/json
{"documentId":"123"}
--95b77841-292d-4a0b-a689-787fcc0aa889
Content-Disposition: form-data; name="document"; filename="document.pdf"
Content-Type: application/pdf
%PDF-1.4
....
%%EOF
--95b77841-292d-4a0b-a689-787fcc0aa889--
How can I save the 2nd part as a valid PDF file to disk?
Hi I use request Module in Nodejs.
There is the code below:
const response = await request.post({
uri: "https://item.rms.rakuten.co.jp/rms/mall/rsf/item/vc",
headers: {
Host: "item.rms.rakuten.co.jp",
Origin: "https://item.rms.rakuten.co.jp",
Referer: "https://item.rms.rakuten.co.jp/rms/mall/rsf/item/vc",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": buildForm(data).length,
Cookie: cookies~,
Accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7,id;q=0.6",
"Cache-Control": "max-age=0",
Connection: "keep-alive",
"sec-ch-ua": `"Google Chrome";v="87", " Not;A Brand";v="99", "Chromium";v="87"`,
"sec-ch-ua-mobile": "?0",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": 1,
"User-Agent":
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
},
formData: buildForm(data),
})
const buildForm = (data) => {
const keys = Object.keys(data);
const form = [];
for (let i = 0, l = keys.length; i < l; i++) {
if (typeof data[keys[i]] === "string") {
const data_value_buf = Buffer.from(data[keys[i]]);
const data_value_convert = encoding.convert(
data_value_buf,
"EUCJP",
"UTF8"
);
form.push(keys[i] + "=" + encoding.urlEncode(data_value_convert));
} else if (typeof data[keys[i]] === "undefined") {
form.push(keys[i] + "=" + "-");
} else {
form.push(keys[i] + "=" + data[keys[i]]);
}
}
return form.join("&");
}
the data is Json type.
When I call the request, I got the broken string response.
so, I added encoding: null, in request post option, like
const response = await request.post({
uri: "https://item.rms.rakuten.co.jp/rms/mall/rsf/item/vc",
encoding: null,
headers: {
Host: "item.rms.rakuten.co.jp",
~~~~
then I use Iconv Module.
const iconv = new Iconv("EUC-JP", "UTF-8//translit//ignore");
const res = iconv.convert(response);
How to show the response without broken string
Also the response headers is below
Cache-control: no-store, no-cache
Connection: close
Content-Encoding: gzip
Content-Type: text/html; Charset=EUC-JP
Date: Tue, 12 Jan 2021 05:28:50 GMT
Pragma: no-cache
Server: Apache
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-frame-options: DENY
X-oracle-dms-ecid: 93mhk0e_y40000000
X-oracle-dms-rid: 0:1
X-XSS-Protection: 0
Please let me know how to get normal response like html tag response
You made a POST request. So you're SENDING data to the server. You don't get a HTML response. You get a response CODE and correspondant headers.
If you used a GET request instead, then the server could send you a HTML response. See that I said COULD. Not necessarily will. You can get JSON, or just a return code for example.
In this case, although it's not appearing completely, you can see a 200 result code in the top part of your image. This tell us that your request was successfull. And the headers are what you translated. But the relevant information is that the server returned a 200 code.
So or you GET something or you POST something. You can't get HTML while posting. In a post you send the data in the body of the request and then receive just the result code you received, or any relevant error code.
FYI, there are several other HTTP methods besides POST and GET, but for the moment stay with those 2 and when you really understood them you look the other ones.
I want to make the following http request
POST /v1/images HTTP/1.1
Host: api.medium.com
Authorization: Bearer 181d415f34379af07b2c11d144dfbe35d
Content-Type: multipart/form-data; boundary=FormBoundaryXYZ
Accept: application/json
Accept-Charset: utf-8
--FormBoundaryXYZ
Content-Disposition: form-data; name="image"; filename="filename.png"
Content-Type: image/png
IMAGE_DATA
--FormBoundaryXYZ--
It is Medium API
I have attempted following.
var axios = require("axios")
var data = (await axios("https://example.com/image.png")).data;
axios.post("https://api.medium.com/v1/images",{image: data},{
headers: {
"Content-Type" : "multipart/form-data",
"Authorization" : "Bearer " + process.env.key
}
}).then(x=>console.log(x.data))
And I get following error.
Error: Request failed with status code 400
It uses Medium API to upload image, I want to fetch a remote image, and convert it into multipart/form-data and upload it via API, the HTTP request seems confusing, I want the equivalent axios code, someone please help?
Try using FormData instead of plain object?
Example should be like this
const formData = new FormData();
formData.append('image', data);
axios.post('https://api.medium.com/v1/images', formData, {
headers: {
"Content-Type" : "multipart/form-data",
"Authorization" : "Bearer " + process.env.key
}
});
Reference: How to post a file from a form with Axios
I'm encountering a problem when I tried to ask he REST API from Microsoft Azure.
I want to get data about cost management from Azure.
I'm using Postman.
Here is my auth request to have the auth token :
POST /0409a1ac-f7e5-42e3-bcf9-67b730924d00/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
User-Agent: PostmanRuntime/7.15.2
Accept: */*
Cache-Control: no-cache
Postman-Token: c387a38f-a7ec-4ea7-9496-b03c6ede7bf2,406a808c-8c32-4f85-b587-ebcb68f2245c
Host: login.microsoftonline.com
Cookie: x-ms-gateway-slice=prod; stsservicecookie=ests; fpc=AgTu1H7GJ8tPjlaIdg4GZEbOnogPAQAAAPOz7NQOAAAA
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 607
Connection: keep-alive
cache-control: no-cache
Content-Disposition: form-data; name="grant_type"
client_credentials
------WebKitFormBoundary7MA4YWxkTrZu0gW--,
Content-Disposition: form-data; name="grant_type"
client_credentials
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="client_id"
2456f84e8f4:sd87g^lF
------WebKitFormBoundary7MA4YWxkTrZu0gW--,
Content-Disposition: form-data; name="grant_type"
client_credentials
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="client_id"
2456f84e8f4:sd87g^lF
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="client_secret"
qer+sfggr87qf1gGGRD94f
------WebKitFormBoundary7MA4YWxkTrZu0gW--,
Content-Disposition: form-data; name="grant_type"
client_credentials
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="client_id"
2456f84e8f4:sd87g^lF
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="client_secret"
qer+sfggr87qf1gGGRD94f
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="resource"
https://management.azure.com/
------WebKitFormBoundary7MA4YWxkTrZu0gW--
My second request :
GET /providers/Microsoft.Billing/billingAccounts/user#mail.com/providers/Microsoft.CostManagement/exports?api-version=2019-01-01 HTTP/1.1
Host: management.azure.com
Authorization: Bearer ****
User-Agent: PostmanRuntime/7.15.2
Accept: */*
Cache-Control: no-cache
Postman-Token: 65deb91a-9cbb-4a4f-afe4-9b9c4e16b1bd,269a4983-a20d-4fa0-abf9-284d05ec59ef
Host: management.azure.com
Cookie: __Correlation_SessionId=4fdf1457-269b-4d36-a186-639916ab5d1b
Accept-Encoding: gzip, deflate
Connection: keep-alive
cache-control: no-cache
And error I have :
{
"error": {
"code": "401",
"message": "Puid is null/empty. Puid must be present in the header for user to get authorized."
}
}
I didn't already see this error anywhere.
I can't find what's that PUID in Azure.
I also think that I don't put the correct {BillingAccountId}. I don't know how to get it.
Can you guys help me ?
Thank You !
For getting the Access token i would suggest you to use below end point
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=342fb089-9dg3-46f6-9cfs-4f2164897865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
Please ensure to provide the right access to the application.
Additionally for your ease of use you can set a pre-requisite script in postman for getting the token.
Here is the code for the same:
var client_id = pm.environment.get("client_id");
var client_secret = pm.environment.get("client_secret");
var token_endpoint = pm.environment.get("token_endpoint");
var scope = pm.environment.get("scope");
pm.sendRequest({
url: token_endpoint,
method: 'POST',
header: {
'Content-Type': 'multipart/form-data',
},
body: {
mode: 'formdata',
formdata: [
{key: "grant_type" , value: "client_credentials"},
{key: "client_id" , value: client_id},
{key: "client_secret" , value: client_sercret},
{key: "scope" , value: scope}
]
}
}, function(err, response) {
const jsonResponse = response.json();
console.log(jsonResponse);
pm.environment.set("access_token", jsonResponse.access_token);
console.log(pm.environment.get("access_token"));
});
You can refer this link for postman automation:
Hope it helps.
Data sent from Node via Mac. This fails:
POST / HTTP/1.1
Accept: application/json, text/plain, */*
Content-Type: multipart/form-data; boundary=--------------------------410170969577572462482590
Authorization: Basic U3dlY2q9DdlRvQ29uqdGFjdDpVM2RsWTI5RGRsUnZqRMjl1ZEdGamRB
User-Agent: axios/0.18.0
Content-Length: 437
Host: localhost:3000
Connection: close
{
"_overheadLength": 105,
"_valueLength": 5,
"_valuesToMeasure": {},
"writable": false,
"readable": true,
"dataSize": 0,
"maxDataSize": 2097152,
"pauseStreams": true,
"_released": false,
"_streams": {
"0": "----------------------------097921969493700670690484\r\nContent-Disposition: form-data; name=\"Domain\"\r\n\r\n",
"1": "Test"
},
"_currentStream": {},
"_insideLoop": false,
"_pendingNext": false,
"_boundary": "--------------------------097921969493700670690484"
}
Data sent from Postman from Windows. This works:
POST / HTTP/1.1
Content-Type: multipart/form-data; boundary=--------------------------214255515908701131866697
Authorization: Basic U3dlY29DwerdlRvQ29uwerdGFjdDpVM2RsWTwerI5RGRsUnZRMjl1ZEdGamRB
User-Agent: PostmanRuntime/7.15.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 4af4ff14-1abd-4ab7-9e01-5ddd846acfa9
Host: localhost:3020
accept-encoding: gzip, deflate
content-length: 383
Connection: keep-alive
----------------------------214255515908701131866697
Content-Disposition: form-data; name="Domain"
test
--
It seem's node add row brakes: \r\n\r\n here and there.
This causes a failure from a windows server when I post data to it: "Line length 100 exceeded".
See this question: Sending post request multipart form data. Error from some microsoft service "Line length limit 100 exceeded"
I'm using this the form-data package to post data combined with axios.
Is it possible to add some filter/middleware etc that removes alla /n/r etc in my post request?
Update
My request from node:
const form_data = new FormData();
form_data.append('Domain', 'test');
const request_config = {
headers: {
"Authorization": "Basic dffdg",
"Content-Type": `multipart/form-data; boundary=${form_data._boundary}`
},
data: form_data
};
await axios.post(url, form_data, request_config).then(response => {
try removing data from request_config.
const form_data = new FormData();
form_data.append('Domain', 'test');
const request_config = {
headers: {
"Authorization": "Basic dffdg",
"Content-Type": `multipart/form-data; boundary=${form_data._boundary}`
},
//data: form_data
};
await axios.post(url, form_data, request_config).then( /* ... */ )
from axios/axios documentation
NOTE
When using the alias methods url, method, and data properties don't need to be specified in config.