POSTing a nested object ruins the encoding in NodeJS Backend - javascript

I am having trouble sending JSON data that contains special characters like ` to my Node Express server.
I posted How can I render UTF-8 characters in JSX without using dangerouslySetInnerHTML in 2020 earlier, but I think I am approaching the problem incorrectly.
The Problem:
When I submit my JSON form data using an HTTP Client, my req.body HTMLifies special characters:
// Sending a nested JSON.stringified Object
const response1 = await fetch(
`${baseUrl}/chhands/${granthState.lastChhand.id}/pauris`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
pauri: formattedTuk,
last_pauri_id: granthState.lastPauri?.id,
}),
}
);
Here is a result of the console.logging {pauri: formattedTuk, last_pauri_id: granthState.lastPauri?.id}:
What it looks like on the backend when I submit the nested JSON object:
Here is where the where I am even MORE confused:
Here, instead of sending a nested object, I only send the formattedTuk [Array] object, which looks like:
[
{
line_number: 1,
content_unicode: 'ਆਪ ਅਛਤ ਸਮਰੱਥ ਪ੍ਰਭੁ ਦਈ ਬਡਾਈ ਨਾਮ ।',
content_gs: 'Awp ACq smr`Q pRBu deI bfweI nwm [',
content_transliteration_english:
"aap achhat samara'th prabh dhiee baddaiee naam |",
first_letters: 'ਆਅਸਪਦਬਨ',
thamkis: [],
vishraams: [],
},
];
// Sending the raw array object stringified {}
const response2 = await fetch(
`${baseUrl}/chhands/${granthState.lastChhand.id}/pauris`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formattedTuk),
}
);
What it looks like on the backend when I submit the ONLY the Array Object:
Other things I've tried:
Used Axios (instead node-fetch) and it gave the same effect
Used POSTMAN and it had the same effect
Double checked my Content-Type and charset but it all looks good.
Here is my Express middleware settings. I was using body-parser before, but it seems that express.json() is giving me the same effect. I've also seen people recommend using qs.stringify() but what I am doing seems fairly simple.
app.use(morgan('tiny'));
app.use(helmet());
app.use(express.json());
app.use(cors());
Updates:
Here is the exact "Copy as Fetch" value:
fetch("http://localhost:1469/api/v1/chhands/53/pauris", {
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/json",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site"
},
"referrer": "http://localhost:3000/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": "{\"pauri\":[{\"line_number\":1,\"content_unicode\":\"ਆਪ ਅਛਤ ਸਮਰੱਥ ਪ੍ਰਭੁ ਦਈ ਬਡਾਈ ਨਾਮ ।\",\"content_gs\":\"Awp ACq smr`Q pRBu deI bfweI nwm [\",\"content_transliteration_english\":\"aap achhat samara'th prabh dhiee baddaiee naam |\",\"first_letters\":\"ਆਅਸਪਦਬਨ\",\"thamkis\":[],\"vishraams\":[]}],\"last_pauri_id\":60}",
"method": "POST",
"mode": "cors",
"credentials": "omit"
});

Related

can't fetch msgraph data using vanilla js

I am trying to pull data from the endpoint https://graph.microsoft.com/v1.0/me/. I have done this using python but I can't seem to fetch data from Microsoft Graph using vanilla js.
When I attempt to perform a fetch request. I get a 200 response but nothing is inside the response object.
Here is the fetch code:
fetch("https://graph.microsoft.com/v1.0/me/", {
method: "GET",
"headers": {
"authorization": "Bearer ENTERTOKENHERE"}
}).then(data =>{console.log(data)});
I get a response of:
Response {type: 'cors', url: 'https://graph.microsoft.com/v1.0/me/', redirected: false, status: 200, ok: true, …}
but I am expecting more of a response like the one I get from the https://developer.microsoft.com/en-us/graph/graph-explorer website like this:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"businessPhones": [],
"displayName": "Edd Bighead",
"givenName": "Edd",
"jobTitle": null,
"mail": "Edd#conglomo.onmicrosoft.com",
"mobilePhone": null,
"officeLocation": null,
"preferredLanguage": "en-US",
"surname": "Bighead",
"userPrincipalName": "Edd#conglomo.com",
"id": "2fa321d9-bda3-41c1-8be8-5d4049ed8765"
}
Is there anything I am missing to get the data from msgraph using vanilla js only?
I figured it out - I needed to jsonize the data then print that data. Can't believe I missed that. lol
fetch("https://graph.microsoft.com/v1.0/me/", {
method: "GET",
"headers": {
"authorization": "Bearer ENTERTOKENHERE"}
}).then(response => response.json())
.then(data => {console.log(data)})

Request in javascript (from python)

I have attempted to create a request in javascript, that has previously worked using python just fine.
the following is an accurate representation of the code I used to post the request with python:
url = 'https://website.com/api/e1'
header = {
'authorization': 'abcd1234'
}
payload = {
'content': "text",
}
r = requests.post(url, data=payload,headers=header )
This (above) works just fine in python.
now what I did in javascript is the following:
payload = {
"content": "this is text",
};
fetch("https://website.com/api/e1", {
method: "POST",
headers: {
"authorization":
"abcd1234",
},
body: JSON.stringify(payload),
});
but this is returning the error
400- Bad request
When using data parameters on python requests.post, the default Content-Type is application/x-www-form-urlencoded(I couldn't find it on the document, but I checked the request. If you know, please leave a comment).
To achieve the same result with fetch, you must do as follows.
const payload = {
'content': 'this is text',
};
fetch('https://website.com/api/e1', {
method: 'POST',
headers: {
'authorization': 'abcd1234',
},
body: new URLSearchParams(payload),
});
You don't need to do this body: JSON.stringify(payload), rather you can simply pass payload in body like this body:payload

Getting variable from array then pass to url on nodejs request module

I have this array and need to pass all the variables inside the request url.
I've tried as result.variable1, result['variable1'], result[0], but nothing works.
How can access each variable inside the array and pass to url?
result.push({variable1: string1, variable2: string2});
request.post({
url: "mydomain.com/text="Hi"+result[variable1]+"\\n"+result[variable2]+"Hello!",
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
},
rejectUnauthorized: false,//add when working with https sites
requestCert: false,//add when working with https sites
agent: false,//add when working with https sites
form: {
myfield: "myfieldvalue"
}
}, function (response, err, body){
console.log('Body:',JSON.parse(body));
}.bind(this));
result.push({variable1: string1, variable2: string2});
This will result in the array becoming as
result = [{variable1: string1, variable2: string2}].
So if you want 'variable1', you need to access it as result[0].variable1.

Errors while trying to "Put" JSON Data

I am working with the Hubspot API and I am trying to modify the close date of a deal via the "PUT" Method by sending JSON Data. But I am getting errors such as
{ status: 'error', message: 'Invalid input JSON on line 1, column
15: Can not deserialize instance of java.util.ArrayList out of
START_OBJECT token', correlationId:
'b8b47229-184d-40b3-b402-9e3dd684b217', requestId:
'd364fe8dac5e876639928dd0d04045fd' }
This is the code that I have written-
fetch('https://api.hubapi.com/deals/v1/deal/103361780?hapikey=', {
method: 'put',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({"properties":{name: "closedate", "value": 1528744207881}})
}).then(res=>res.json())
.then(res => console.log(res));
This is the JSON Data that I am trying to pass
{
"properties":[
{
"name": "closedate",
"value": 1528744207881
}
]
};
And here is the documentation of making a PUT request via the Hubspot API.
I am able to successfully update the value via POSTMAN.
Any help on this matter would be greatly appreciated.
You are missing brackets - [] and on the backend, they are waiting for an array to deserialize it to Arraylist.
Try fetch with this body:
{"properties":[{"name": "closedate", "value": 1528744207881}]}

HTTPS request not posting body of REST request

I'm trying to POST to an API endpoint on my server. I know my endpoint works because if I use Advanced REST Client, I can hit it and get a JSON response as expected. The problem seems to be that no data is being sent in the body of my request despite calling request.write(postData) which contains a key, value pair. Without this data being sent in the body, my server returns a 401 error as expected without this information. Printing out the content of the POST server-side is empty but I'm clueless as to why it's empty.
var postData = querystring.stringify({
"access_token" : accessToken,
"id": applianceId
});
var serverError = function (e) {
log("Error", e.message);
context.fail(generateControlError(requestName, "DEPENDENT_SERVICE_UNAVAILABLE", "Unable to connect to server"));
};
var callback = function(response) {
var str = "";
response.on("data", function(chunk) {
str += chunk.toString("utf-8");
});
response.on("end", function() {
result = generateResult(CONTROL, requestName.replace("Request", "Confirmation"), messageId);
context.succeed(result);
});
response.on("error", serverError);
};
var options = {
hostname: REMOTE_CLOUD_HOSTNAME,
port: 443,
path: REMOTE_CLOUD_BASE_PATH + "/" + endpoint,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
};
var request = https.request(options, callback);
request.on("error", serverError);
//This doesn't seem to write anything since if I print out the POST
//data server-side it's empty; however, if I print out the value of
//postData here, it looks as expected: 'access_token=xxxxx'
request.write(postData);
request.end();
I have testing you code again httpbin.org/post and it seems that it is working.
I believe that the issue related to, that your should POST application/json and not "application/x-www-form-urlencoded
Please try to change the header
headers: {
"Content-Type": "application/json"
}
Then, try to change the postData to JSON string:
var postData=JSON.stringify({access_token:"xxxxx"})
To be sure that problem you success to send and the problem is not local (maybe there is an issue in your server), change the target to mirror URL:
var options = {
hostname: "httpbin.org",
path:'/post',
port: 443,
method: "POST",
headers: {
"Content-Type": "application/json"
}
};
If there is no problem in your NodeJS version, the is the response you should get: (It is mean that the server got the posted data)
{
"args": {},
"data": "{\"access_token\":\"xxxxx\"}",
"files": {},
"form": {},
"headers": {
"Content-Length": "24",
"Content-Type": "application/json",
"Host": "httpbin.org"
},
"json": {
"access_token": "xxxxx"
},
"origin": "5.29.63.30",
"url": "https://httpbin.org/post"
}
BTW: I really recommend you to move to a library to manage the request for you:
https://github.com/request/request - Very popular
https://github.com/request/request-promise - For popular who like to use the Promise syntax (The next thing in JavaScript)
https://github.com/visionmedia/superagent - For people who like to write same code in Browser & Server

Categories