I have the code below which is supposed to send a POST request but with an empty JSON body:
request.post({
url: url,
headers: {
"data_digest": 'muZ7EcapQZVb77RF',
"partner_code": "ebfebc241db9b9c1a",
"msg_type": "GET_BASEDATA_TRANSPORT",
"msg_id": '1590464383047',
"Accept-Language": "zh-cn"
},
json: true,
body: {}
}, function(error, response, body) {
console.log(body);
});
However this keeps returning
'System Exception:\r\ntype org.springframework.web.HttpMediaTypeNotAcceptableException\r\nmessage:Could not find acceptable representation'
But using Postman I'm able to correctly send POST request with the exact same headers but just an empty {} in the Body parameter with Raw format.
How can I send a POST request with an empty JSON body in Node JS?
Your way of sending the body is fine. If you'd look at the actual request sent (for example using Fiddler or Wireshark) you'd see the body is sent correctly. The problem is something else - instead you'd see that the headers are not the exact same.
Using json (either with json: true and body, or as you do it, with json as object) also automatically sets the Accept header to application/json and attempts to parse the response as JSON.
It seems that this server chiguotest.ytoglobal.com has a bug, where it returns JSON but does not handle the Accept header correctly (I tested it and it seems the server "thinks" it is returning text/plain). So request is (correctly) telling the server "I expect you to return JSON", but the server says "What, JSON? No I don't know how to return JSON, only text, sorry.". Yet, it in fact does return JSON.
You can circumvent this server bug by explicitely sending an Accept: */* header:
request.post({
url: url,
headers: {
"data_digest": 'muZ7EcapQZV',
"partner_code": "ebfebc241db9b9c",
"msg_type": "GET_BASEDATA_TRANSPORT",
"msg_id": '1590464383047',
"Accept-Language": "zh-cn",
"Accept": "*/*"
},
json: true,
body: {}
}, function(error, response, body) {
console.log(body);
});
My output:
{
"data": {
"productKinds": [
{
"productCnname": "(美国)测试用-不拉G单号",
"productCode": "1",
"productEnname": "1",
"productServerhawbcodeNeed": "Y"
},
{
"productCnname": "散客可见产品",
"productCode": "111",
"productEnname": "内部产品",
"productServerhawbcodeNeed": "N"
},
... many more entries ...
]
},
"errorCode": "SUCCESS",
"errorMsg": "成功",
"status": true
}
Related
I am sending an object with fetch method from a webpage, that must then be appended to a json file on server. Here is how I am sending it:
fetch(url + '/send', {
method: 'POST',
body: {a: 1, b:2}
})
However, upon reading, all I get is an empty object.
When I send Body with Postman POST request, it works fine. Please help me find out why that is.
{
"a":"1",
"b": "2"
}
You need to send the appropriate Content-Type header with your POST request:
fetch(url + '/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: {a: 1, b:2}
})
I put the grant_type parameter in the request body as the documentation shows, but Microsoft Graph still complains that it's not there;
const tokenRequestBody = [
"grant_type=client_credentials",
"scope=https%3A%2F%2Fgraph.microsoft.com%2F.default",
`client_secret=${config.appClient.password}`
].join("&");
request.post(
{
url: tokenRequestUrl,
json: true,
headers: {
"content-type": "application/application/x-www-form-urlencoded"
},
body: tokenRequestBody
},
(err, req, body) => {
console.log(body.error_description);
// Logs: The request body must contain the following parameter: 'grant_type'.
}
);
I figured it out. I had to use form instead of body for the request node module.
What I'm trying to do is use the OctoPrint Rest API. I keep running into an error though when I'm trying to do POST requests that require a command. Here's an example of that in the docs.
POST /api/connection HTTP/1.1
Host: example.com
Content-Type: application/json
X-Api-Key: abcdef...
{
"command": "connect",
"port": "/dev/ttyACM0",
"baudrate": 115200,
"printerProfile": "my_printer_profile",
"save": true,
"autoconnect": true
}
What I'm most confused about is where I include the command or the port values. Here's what I'm currently doing.
var self = this;
request({
url: OCTOIP + "/api/connection",
method: "POST",
"content-type": "application/json",
headers: {
"X-Api-Key": KEY
},
body: JSON.stringify({"command": "connect"})
}, function(error, response, body) {
//var info = JSON.parse(body);
if (error) {
console.log(error);
self.tell("Could Not Connect");
}
else {
console.log(body);
self.tell("Connected to printer.");
}
});
What happens is I keep getting this error message.
Expected content-type JSON
I've tried changing content-type to just json, I've tried getting rid of the JSON.stringify and just putting it as {"command": "connect"}. Or even dropping the curly brackets altogether. Another thing I tried was using form and instead of the body. None of those have worked. What am I doing wrong here?
Fixed the issue. It turns out it wasn't working because I didn't put the content-type in the header.
I have a Lambda proxy integration enabled, and setting the response headers as part of Lambda output and API Gateway that will return them as part of the HTTP response to the client.
Sample code:
callback(null, {
"statusCode": 302,
"Location" : "https://somewebsite.com"
"headers": { "headerName": "headerValue", ... },
"body": "..."
});
I need to send out 3 cookies in the headers. I tried. But, failed:
callback(null, {
"statusCode": 302,
"Location" : "https://somewebsite.com"
"headers": { "Set-Cookie": [cookie1String, cookie2String, cookie3String] },
"body": "..."
});
[Edit]
I concatenated the cookie and passed in as the response, the client gets the cookie. But when the client calls the target in "location", the request does not have the cookie in the header.
callback(null, {
"statusCode": 302,
"Location" : "https://somewebsite.com"
"headers": { "Set-Cookie": c1=cookie1String;c2=cookie2String; c3=cookie3String] },
"body": "..."
});
Please help in sending these 3 cookies out to my client.
Use multiValueHeaders instead of headers.
const response = {
isBase64Encoded: true,
statusCode: 200,
multiValueHeaders : {"Set-Cookie": [`language=${language}`, `theme=${theme}`]},
body: JSON.stringify('User profile set successfully')
};
callback(null, response);
If you need it to be smarter, consider something like
function createHeaders(headers) {
const defaultHeaders = {
'Access-Control-Allow-Origin': '*',
};
const allHeaders = Object.assign({}, defaultHeaders, headers);
const singleValueHeaders = {};
const multiValueHeaders = {};
Object.entries(allHeaders).forEach(([key, value]) => {
const targetHeaders = Array.isArray(value) ? multiValueHeaders : singleValueHeaders;
Object.assign(targetHeaders, { [key]: value });
});
return {
headers: singleValueHeaders,
multiValueHeaders,
};
}
Then use it in the callback function.
callback(null, {
statusCode: status || 200,
body: JSON.stringify(body),
...createHeaders({ 'Set-Cookie': cookie }),
});
API gateway does not let you map the same header more than once. I got around by using different casing to set-cookie method.
callback(null, {
"statusCode": 302,
"Location" : "https://somewebsite.com"
"headers": { "Set-Cookie": cookie1, "set-Cookie": cookie2 },
"body": "..."
});
I would say that your issue is related to the fact that your response object in the callback is not formatted the way the api gateway expects.
These links reference aws documentation specifically to that.
http://docs.aws.amazon.com/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html
Issue with your code...
'location' does not look like a valid property
Make sure your header key/value pairs are actual JSON objects using something like JSON.stringify
Don't forget to enable logs for both api gateway and lambda with full requests and responses. These two logs will help you debug.
I have a very large xml which gets generated using wsjs node module. it looks like
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:diag="http://diagnostic.ws.fcrewards.test.com/" xmlns:ws="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><soapenv:Header><ws:Action>http://diagnostic.ws.fcrewards.test.com/doEcho</ws:Action><ws:To>https://ws.mastercard.com/mtf/MRS/DiagnosticService</ws:To><ws:MessageID>35b479f1-5a54-e9a4-5551-0f15507f54b8</ws:MessageID><ws:ReplyTo><ws:Address>http://www.w3.org/2005/08/addressing/role/anonymous</ws:Address></ws:ReplyTo><o:Security><u:Timestamp wsu:Id="_0" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><u:Created>2017-02-24T17:13:13Z</u:Created><u:Expires>2017-02-24T17:18:13Z</u:Expires></u:Timestamp><o:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" u:Id="sec_0">MIID1zCCAr+gAwIBAgIRAIVAIPeDa+CgeYorExNgwDQYJKoZIhvcNAQELBQAwgYUxCzAJBgNVBAYTAkJFMRwwGgYDVQQKExNNYXN0ZUNhcmQgV29ybGR3aWRlMSQwIgYDVQQLExtHbG9iYWwgSW5mb3JtYXRpb24gU2VjdXJpdHkxMjAwBgNVBAjdjdjjdjdjjdjjdQgUFJEIE1lc3NhZ2VzIFNpssssssssssssssssssssssssIxNjIxMzcwN1owZjEbMBkGA1UEAxMSbXRmLkNIUy5wYXlGb3J3jdjjdjdjdjjdjjndkwlklwlwlwww25pbmcgU1cxDjAMBgNVBAsTBUNIUyAxMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM675qti1N/aMP+YsPe9UIaJasISYzIpEoysKhClmWfBTqJTrcw0UWnraSOGqdPvEpgcLdW2BwnZ+T2gmcLa/BY69hW+CYm0pR0px9MPNuP77YcJCS5d6ffuHvTlkVpBq2hWVhOck0X0uhu+m2I6G8Dshi8yiBJohs+jpuf63OxVtBTemFNM5pVDdB5z7sYhkrdcNzlSoPTKNcTFfZgnj0G6iwkb4XK1mSlXbQL8jYEPPZWDdxPFl1SrSnwUoyl3r84SZrV13JstZ4YrolAm8mmKB7pU+bJ46+zpeYDRDo/YH4cxSpkyPUuwB27PtLk1J/9FgBNLfY0XQnlk/b3Mm3MCAwEAAaNgMF4wHwYDVR0jBBgwFoAU66ASd4JT9FhYrwHp4f9kBT5H2aowDAYDVR0TBAUwAwIBADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFJ1obzmA1M2PIL8GumtHSIdwUrZMMA0GCSqGSIb3DQEBCwUAA4IBAQASqfFjdTt74OHwmEJVlO3pYnnHcxvDU0v7+2xTTMpWSAKmfDGf5j71UDsa6E/ymclcz/mdbsHSvyYii8TsrYK8Nyq6o2nTAQ0mhRhSpip7kjv5eQ0PtJZhl0Je7W9b3GIS1M5IbNN7xusKNHaJSg7ZIf/gUwWuBOq1CxABE0xRGY5b5e6giglP2iJwgeOHukmeGiLck3HGqZjei+T/Fnvsyy7hQ6qzGTDZg6B6yd1ojMZddmjDV8QsQfUQWM0//rvORZup98VP7I9LmrDBQuu7cPPy0Vg8VRWZC9wrM82e6IHl1uMovU12PCth1vAcSyTjuorNn5NoQg8FIoLCdgLk</o:BinarySecurityToken><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI="#_0"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>qNgtbxFDtGr1QCRG4ZnGSzfWqQ+GZJkuQAHgTxcI4B8=</DigestValue></Reference></SignedInfo><SignatureValue>ZqHJTwD91tcddddddddd3uZkuChVE0BHEx55YF3kGNw1D55VbunmbNZkmxxkuBvyAMjns/DJ8/duThXhlAmyPLYhRgj4djz8smJbksago1Tb+DFT8RQ4tOVPD2TPSaC5wrwA9g9zCCpPDHHv5FmZ4TIxwkPjG37MBqOIgUF8cUkL9kXU0sIJrUQddddddddddddddddddddddddddddddddddddddddddddddddddddddwsRtcjKDksvWpMBj0oSysWi+8/ce2HnO4nOuhrvX66BDOAyPL+avL2+JNTlA==</SignatureValue><KeyInfo><o:SecurityTokenReference><o:Reference URI="#sec_0" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/></o:SecurityTokenReference></KeyInfo></Signature></o:Security></soapenv:Header><soapenv:Body><diag:doEcho>Cieran</diag:doEcho></soapenv:Body></soapenv:Envelope>
when I send this request using request module of node.js
request.post({
url: ctx.url,
body: ctx.request,
headers: {
"SOAPAction": ctx.action,
"Content-Type": ctx.contentType,
"ContentLength": Buffer.byteLength(ctx.request),
"MIME-Version": "1.0",
"Connection": "Keep-Alive",
"AcceptEncoding": "gzip"
},
encoding: null,
rejectUnauthorized: true,
agentOptions: ctx.agentOptions
},
function(error, response, body) {
ctx.response = body
if (response) {
ctx.resp_headers = response.headers
ctx.resp_contentType = response.headers["content-type"]
}
if (error) ctx.error = error
else ctx.statusCode = response.statusCode
callback(ctx)
})
ctx.request has the whole xml in it as 1 big string
I always get Authorization failed error because endpoint is out rightly rejecting my request.
But if I take the xml and put it in SOAPUI and do format xml then I get the right result.
So I concluded that since i'm sending the body as 1 big xml the endpoint doesn't like my request.
What's the workaround for this?
Is there any other node module available which can format the xml or break it up in small strings?