Retrieving response payload elements from XMLHttpRequest - javascript

I'm sending a JSON request (an applicative login but the kind of request doesn't matter) to a server with the following function:
function login() {
var payload = {
"api_key" : "", "cmd" : "login",
"params" : {}
}
payload["params"]["username"] = document.getElementById("uname").value
payload["params"]["password"] = document.getElementById("passwd").value
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:4000/api", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.setRequestHeader("Accept", "application/json");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
resp = JSON.parse(xhr.responseText);
console.log("resp.status=" + resp.status);
console.log("resp.[\"status\"]=" + resp["status"]);
}
}
xhr.send(JSON.stringify(payload));
}
I'm actually getting the correct reply in the responseText field. For example, if the credentials are wrong, I get
{
"status": "ko",
"errors": [
{
"cmd": "login",
"long": "Login error : 'user-20' has no access to the system",
"short": "login_error"
}
]
}
If the credentials are OK I get
{
"status": "ok",
... some additional data
}
Yet, I can't manage to get the status field : resp.status or resp["status"] are always undefined. Same if the call is done in asynchroneous mode (xhr.open("POST", "http://localhost:4000/api", false);) or if I don't JSON.parse() the reply, ie: resp = xhr.responseText;.
Update - 2017.09.06
I finally found a way to get it working, but I don't quite understand why it is so. I actually changed
resp = JSON.parse(xhr.responseText);
into
resp = JSON.parse(JSON.parse(xhr.responseText));
To figure this out, I printed typeof(xhr.responseText) which is a sting. Actually typeof(JSON.parse(xhr.responseText)) is also a string and this is why it has no fields like status. Eventually, parsing xhr.responseText twice gives an object from which I actually can retrieve my data.
If somebody has a clue about what is happening, I would be interested... I don't know if this is related, but the app server that is sending the JSON is the latest version of Elixir/Phoenix, ie, 1.5/1.3 and JSON encoding/decoding is done with poison.

This is because you have assigned the resp variable to responseText
resp = JSON.parse(xhr.responseText);
To get the response code
respCode = xhr.status
Or if you want both in the same resp variable you could do
resp = {
responseText: xhr.responseText,
status: xhr.status
}
Then you can access them as resp.responseText and resp.status

Related

Post metafields to shopify admin API

I´m trying to save customers metafields using the shopify admin api, i´m using this code
var data = {
"metafield": {
"namespace": "test",
"key": "testkey",
"value": "lorem ipsum",
"value_type": "string"
}
}
var xhr = new XMLHttpRequest();
xhr.open("POST", "/admin/customers/0000000000/metafields.json", true);
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", 'Basic ' + btoa('myuser:mypass'));
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function () {
console.log(xhr.responseText);
};
xhr.send(JSON.stringify(data)); //RETURNS A CODE 301 WITHOUT RESPONSE MESSAGE
xhr.send(data); //RETURNS A CODE 400 WITH "error 419: unexpected token at 'object Object]'" MESSAGE
Please tell me What I missing?
Thanks a lot
It looks like you are trying to save the metadata to customer id 00000000 in your URL, typically you'll want to have that field supplied dynamically if this is going to be used in a utility tool. Your probably might be that ID is not pointing at an actual customer ID.

Javascript vanilla ajax turn response into array of objects?

I am trying to experiment with javascript on a deeper level. I am building my own $http object that has its own http methods.
var $http = {
get: function(url, success, error) {
httpHelper('GET', url, success, error);
}
};
function httpHelper(type, url, success, error) {
var xmlhttp;
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
if(xmlhttp.status == 200){
success(xmlhttp.responseText);
}
else if(xmlhttp.status == 400) {
error(xmlhttp.status);
}
else {
error(xmlhttp.status);
}
}
}
xmlhttp.open(type, url, true);
xmlhttp.send();
};
On the server I am returning an array of JSON objects with the request.
app.get('/api/players/', function(req, res) {
res.json([
{ name: 'Mike', points: 33 },
{ name: 'Shaq', points: 16 }
]);
});
On the client it seems I am getting a string [{"name":"Mike","points":33},{"name":"Shaq","points":16}].
How can I effectively convert the client side response to an array of JSON objects?
Just use JSON.parse
JSON.parse(xmlhttp.responseText);
Even though a comment has already answered the question, I felt I may as well throw out an actual answer (plus clarification on where to put it!)
You're looking for JSON.parse. Where you put it depends on if your $http object will only be getting JSON responses or not. If it does, then put your JSON.parse in what you send to success:
success(JSON.parse(xmlhttp.responseText));
However, if you also want to accept other types of requests, then put your JSON.parse in your callback that is success.
$http.get('some url', function(result) {
result = JSON.parse(result);
}, function() {
// ...
});

EWS - A token was not recognized in the JSON content

I try to send an email via EWS using Javascript and the REST API.
The OAuth is not the problem so far.
The problem is, if I try to send the email, the Server sends this response:
"{"error":{"code":"RequestBodyRead","message":"Invalid JSON. A token was not recognized in the JSON content."}" (taken from Chrome Debug Console).
Here my Javascript, where the error occurs:
function mailIsRaus(token) {
var gottenParam = JSON.stringify(token);
var jsonObj = JSON.parse(gottenParam);
var leToken = jsonObj['access_token'];
//This is the Token from Active Directory
leToken = "Bearer " + leToken;
var Message = {
"Message": {
"Subject": "TESTING REST API EWS",
"Body": {
"ContentType": "Text",
"Content": "IT WORKED. The EWS is working my friend."
},
"ToRecipients": [
{
"EmailAddress": {
"Address": "johndoe#something.com"
}
}
]
},
"SaveToSentItems": "true"
};
//eMailData = JSON.stringify(eMailData);
$.ajax({
type: 'POST',
beforeSend: function (request) {
request.setRequestHeader("Authorization", leToken);
request.setRequestHeader("Content-Type", "application/json");
},
data: Message,
url: 'https://outlook.office.com/api/v2.0/me/sendmail',
success: function (e) {
console.log('Email sent');
console.log(e);
},
error: function (message) {
console.log(message);
}
});
}
I strictly sticked to MSDN and now, I have no clue, why this error occurs.
If I comment out the "setRequestHeader" I get an error 401 unauthorized.
The token ist correct.
The scope is also correct.
Maybe I made an simple mistake in the "var Massage" or something...
I found the solution by myself.
I had to uncomment the following line of code to:
eMailData = JSON.stringify(eMailData);
Now it is working fine.

CORS: Access-Control-Allow-Origin not equal to supplied origin

I'm trying to send an email from an application using sendgrid. This shouldn't be too difficult, and with PHP I've sent emails before. In this case I want to do it in Javascript as it's part of an Ember application. The first problem is the "No 'Access-Control-Allow-Origin" message, which I tried to solve with CORS. Now I've just got a different error!
Now I'm not sure where to look for tackling this issue. The code I'm using is the following:
(function(){
makeCorsRequest('GET', mailUrl);
})();
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
function makeCorsRequest(type, url) {
var xhr = createCORSRequest(type, url);
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.onload = function() {
var text = xhr.responseText;
console.log(text);
var title = getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
This gives me the error:
The 'Access-Control-Allow-Origin' header has a value 'https://sendgrid.com' that is not equal to the supplied origin. Origin 'http://localhost' is therefore not allowed access.
sendGrid CORS policy does not allow browsers to call their API (except if your are on "sendgrid.api-docs.io" domain) ... You have to send email from your server,
but if just for test or development purpose you can use my demo on github
https://github.com/itisnajim/sendgrid-nodejs
post your data to
http://sendgrid-nodejs-oxailstudiosnode.7e14.starter-us-west-2.openshiftapps.com
Ajax example:
let urlStr = "http://sendgrid-nodejs-oxailstudiosnode.7e14.starter-us-west-2.openshiftapps.com";
const msg = {
"personalizations": [
{"to": [{"email": "example1#mail.com"}]}
],
"from": {"email": "example2#mail.com"},
"subject": "subject example",
"content": [{"type": "text/plain", "value": "example body text"}]
};
$.ajax({
url: urlStr,
type: 'post',
data: JSON.stringify(msg),
dataType: 'json',
contentType: "application/json; charset=utf-8",
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Bearer API_KEY_HERE")
},
success: function(data){
//console.log(data);
//OK: Mail sent!!
},
error: function( jqXhr, textStatus, errorThrown ){
//console.log( errorThrown, textStatus, jqXhr );
if(jqXhr.status === 202 || jqXhr.status === "202"){
//OK: Mail sent!!
}else
console.error("Mail not sent! Err:"+JSON.stringify(errorThrown))
}
})
It looks like you're calling the SendGrid API from an Ember app running in your browser? If so, you probably shouldn't be (for a number of security reasons).
You'll want to make an AJAX request to a server running on your own domain, and have your server
validate that the request is legitimate, and
call the SendGrid API to send the email
Exposing your SendGrid API key, and calling the API directly from a browser exposes your SendGrid account to potential abusers.
For the server-side API call, check out SendGrid's API Clients. You shouldn't need to write the API calls yourself.

How to get "Data" field from xhr.responseText?

I have XMLHttpRequest() function given below
var searchFriendRequests = function (userid) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:6344/api/Registeration/searchFriendrequests?userid=' + userid, false);
xhr.setRequestHeader("Content-Type", "text/xml");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var data = xhr.responseText;
}
}
};
xhr.send(null);
}
where xhr.responseText returns value as
{
"$id": "1",
"ContentEncoding": null,
"ContentType": null,
"Data": [
{
"$id": "2",
"email": "anu#gmail.com"
},
{
"$id": "3",
"email": "anu#gmail.com"
}
],
"JsonRequestBehavior": 1,
"MaxJsonLength": null,
"RecursionLimit": null
}
How can I get the Data field from the responseText?
use JSON.parse(), like:
var data=xhr.responseText;
var jsonResponse = JSON.parse(data);
console.log(jsonResponse["Data"]);
You first need to parse responseText in JSON, for this you should use JSON.parse(). Then you can access it using key.
var json = JSON.parse(xhr.responseText);
var yourData = json.Data; // or json["Data"]
To simply get the email, or any other field, from the Data object, use the following:
data.Data[0].email
WORKING EXAMPLE
For sometime now you can use:
xhr.responseJSON
without any parsing needed. hope it helps
should parse the response to json object first,then get the data field from the response
var responseText = JSON.parse(xhr.responseText),
data = responseText.Data;
When you make your ajax request you can provide dataType option:
dataType: 'json'
For such request when you receive response:
If json is specified, the response is parsed using jQuery.parseJSON before being passed, as an object, to the success handler. The parsed JSON object is made available through the responseJSON property of the jqXHR object.
you can access your data like:
var data = xhr.responseJSON
Full example:
$ajax.({
dataType: 'json',
success: function( xhr ) {
var yourData = xhr.responseJSON;
console.log( yourData );
},
});
var jsonResponse = JSON.parse(xhr.responseText);
console.log(jsonResponse);

Categories

Resources