I'm new to JS. And have a basic silly doubt. Please bear with me.I want to send a request of the form:
{"user":{"username":"myuser","password":"mypass","role":"myrole"}, "organization":"org_name"}
such that the user object can be access by req.body.user and organisation can be accessed by req.body.organization.
But when I'm sending this request:
it translates to-
{
"user[username]": "myuser",
"user[password]": "mypass",
"user[role]": "myrole",
"organization": "org_name"
}
When I just send
{"user":{"username":"myuser","password":"mypass","role":"myrole"}}
then I can access using req.body.user, but not the way mentioned above. Why is this so?
How can I send the request now such that I can access the request.body.user and req.body.organization properly?
EDIT:
This is how the request is sent. Front end: ember, backend node/express:
Ember.$.post("http://"+window.location.hostname+":3000/api/organizations/customer",{"user":{"username":"myuser","password":"mypass","role":"myrole"}, "organization":"org_name"},function(data){
console.log(JSON.stringify(data),null, " ");
});
Receiving side:
console.log(JSON.stringify(req.body,null," "));
I am trying to create the user but req.body.user is undefined. Though I can use user[username] and proceed, but that s now how I want to do
You aren't sending JSON to the server. Passing an object in as data doesn't send it as an object; it simply gets converted to a query string [source]. If you want to send JSON, you need to use JSON.stringify on the data that you send, not the data you receive.
Ember.$.post("http://"+window.location.hostname+":3000/api/organizations/customer",JSON.stringify({"user":{"username":"myuser","password":"mypass","role":"myrole"}, "organization":"org_name"}),function(data){
console.log(data);
});
With the help of Christian Varga's answer to this post, I could further dive in. Though the problem was still not solved, but it gave some insight of how can that be solved.
This is what I did next for such a structure. As per his suggestion, I used JSON.stringify but at a different place:
Ember.$.post("http://"+window.location.hostname+":3000/api/organizations/customer",{"user":JSON.stringify({"username":"myuser","password":"mypass","role":"myrole"}), "organization":"org_name"},function(data){
console.log(data);
});
On the backend server side I could then receive req.body.user. But the req.body.user was stringified JSON. To further access this inner JSON, I had to use JSON.parse.
Though this worked, but I was looking for more better solution, since this backend change worked for my front end implementation, but was failing for RESTClient.
I understood I need to pass the contentType of the data to be sent in the post request. I could not find $.post argument for contentType. So then I used $.ajax call.
Ember.$.ajax({
url: "http://"+window.location.hostname+":3000/api/organizations/customer",
type:"POST",
data: JSON.stringify({user:{username:username,password:password,role:role}, organization_id:organization_id}),
contentType: "application/json; charset=utf-8",
dataType:"json",
success: function(data){
console.log(JSON.stringify(data),null, " ");
}
});
where the username, password, role, organization_id are already assigned variables.
Related
I am trying to authenticate with a remote service through jQuery. First, I verify that I can do this outside of the browser:
curl -X POST -H "Content-Type: application/json" -H "Accept: appliction/json" -d '{"username":"...","password":"..."}' http://example.com/auth
This successfully returns a token.
Now I try it with jQuery:
$.ajax({
url: "http://example.com/auth",
type: "POST",
dataType: "json",
contentType: "json",
data: {username:"...",password:"..."},
error: function(data){alert(JSON.stringify(data))},
success: function(data){alert(JSON.stringify(data))}
});
I get a server error (500). Clearly I am doing something wrong. This is my first time trying to do a POST in jQuery, so I don't know how to identify what the problem is. What am I doing wrong here?
P.S. I can successfully do a GET request through jQuery, if I already have a token:
$.ajax({
url: "http://example.com/stuff?token=f42652adcbfe3ed9d59fae62b5267b8d",
type: "GET",
dataType: "json",
error: function(data){alert(JSON.stringify(data))},
success: function(data){alert(JSON.stringify(data))}
});
The only thing I notice is a difference in the data representations. Look at the data in the original request:
-d '{"username":"...","password":"..."}'
And the data in the AJAX request:
data: {username:"...",password:"..."}
The former wraps the keys in strings, whereas the latter doesn't. The whole thing should be a string too. Try:
data: '{"username":"...","password":"..."}'
This would be more consistent with JSON formatted data in general, I believe. Without wrapping the keys in strings, it may be a JavaScript object but it's not JSON data.
Update: oops missed a comment saying stringify didn't work. I'll leave this for posterity
Sometimes you need to stringify the data when sending Json, otherwise jquery may serialize the object as a param string rather than as a whole object. It depends on how your server binds the request query to the object. though. Can you debug the server request or is that out of your hands?
Try doing (provided you are on a semi modern browser) :
data: JSON.stringify({ your: data})
Thank you everybody for your help. Each little piece of advice helped lead me to the solution. I said it in a comment already, but here is the solution:
The dataType is correctly listed as "json", but the contentType should be listed as "application/json".
The content must be wrapped in JSON.stringify.
Do you post to the same domain as the js was loaded from? If not you need to use jsonp and make sure the server explicitly accepts your request, I believe.
500 Internal Server Error
The server encountered an unexpected condition which prevented it from fulfilling the request.
Json response from the url may be the reason, you can comment the stringfy function and alert the response. You can use try/catch method in response and check the error.
1) Open Network in Tools (f12)
2) Select "Network"
3) Select error row
4) Open "Body" on rights side
5) In title you can see error description eq.
<title>The parameters dictionary contains a null entry for parameter 'Id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Delete(Int32)' in 'BosCatalog.Controllers.ProductsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.<br>Parameter name: parameters</title>
This is killing me. Trying to load data from a different domain from an API-sorts of that I'm trying to write. When sending JSON parameters as POST they get discarded, I've read somewhere that some special headers must be set before_filter:
def cors_headers #set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
headers['Access-Control-Max-Age'] = "1728000"
headers['Access-Control-Allow-Headers'] = 'content-type, accept'
end
Haven't had any luck with these though. Guess it's a browser limitation.
When I try sending the data as GET instead of POST, it gets added to the URL like this:
Completed in 959ms (View: 0, DB: 2) | 200 OK [http://www.somedomain.com/connector/browse/Sport.json?callback=jQuery16105855946165975183_1379526705493&{%22filters%22:[{%22filter%22:{%22attribute%22:%22id%22,%22op
erator%22:%22%3E%22,%22value%22:%222%22}},{%22filter%22:{%22attribute%22:%22id%22,%22operator%22:%22%3C%22,%22value%22:%227523%22}}]}&_=1379526723982]
So Rails basically can't see the filters which are the params that I'm trying to send
Parameters: {"{\"filters\":"=>{}, "id"=>"Sport", "_"=>"1379526723982", "callback"=>"jQuery16105855946165975183_1379526705493"}
The jquery snippet I'm playing with is:
$jq.ajax({url: "http://www.somedomain.com/connector/browse/" + x + ".json" + "?callback=?",
type: "get", // tried post too
dataType: "json", // tried jsonp too
accepts: "json",
data: req_data, // this is JSON.stringified already
processData:false,
contentType: "application/json; charset=UTF-8;",
success: output
});
The sample data I'm trying to send is this
{"filters":[{"filter":{"attribute":"id","operator":">","value":"2"}},{"filter":{"attribute":"id","operator":"<","value":"7523"}}]}
Has anyone an idea on how to sort this out?
Muchos gracias!
Basically the JS SOP prevents us from sending a POST request and reading the response, but this can be worked around like this:
1) Compose the request data, send it as POST. Don’t expect to receive a response. Don’t use on success, use on complete instead. Add a random-ish variable to the request
2) Temporarily store the response on the server side in a file or session variable or memcached server, use the random var mentioned above as key within the store.
3) send a 2nd JSON AJAX call to fetch the cached object.
With memcached, make sure the cached responses get removed from time to time or expire, in my case the app gets a lot of traffic, it would spam my memcache servers with junk if not set to expire.
here's some sample code
So a simple question:
JavaScript needs to send to server that request:
myserver/scipt.php?LANG=EN&AGENT={"Login":{"name":"user","pass":"user"}}
How I need to form url and data in Ajax?
Is this right?
var formData = {
"login":$("#field1").val(),
"pass":$("#field2").val()
};
$.ajax({
url:'http://myserver/scipt.php?LANG=EN&',
type:'GET',
data:'AGENT=' + $.toJSON(formData),
success: function(res) {
alert(res);
}
});
Thank you!
I'd recommend sending JSON via POST instead of GET. GET has some limitations that you want to avoid.
A part from that, yes, your code seems ok.
EDIT:
Sorry, your code is not ok.
Change the data line to:
data: $.toJSON(formData),
You need to send the data to the server in the form of a map ..
Your data is already in json format.. You need not do $.toJSON again
Instead of
data:'AGENT=' + $.toJSON(formData),
send it this way
data:{ 'AGENT' : {'Login' : formData } },
You need to URL encode any strings you want to pass through Ajax.
If jQuery works anything like a normal form, you also need to put all your query string data into data to avoid the existing query string being destroyed.
url:'http://myserver/scipt.php',
type:'GET',
data: {
"AGENT": $.toJSON(formData),
"LANG": "EN"
},
Note, you should use POST requests if you are transmitting user credentials. You don't want them cached or stored in server access.log files.
The service API I am consuming has a given GET method that requires the data be sent in the body of the request.
The data required in the body is a list of id's separated by hypen and could potentially be very large and thus it must be sent in the body otherwise it will likely foobar somewhere in the browsers/proxies/webservers etc chain. Note I don't have control over the service or API so please don't make suggestions to change it.
I am using the following jQuery code however observing the request/response in fiddler I can see that the "data" I am sending is ALWAYS converted and appended to the query string despite me setting the "processData" option to false...
$.ajax({
url: "htttp://api.com/entity/list($body)",
type: "GET",
data: "id1-id2-id3",
contentType: "text/plain",
dataType: "json",
processData: false, // avoid the data being parsed to query string params
success: onSuccess,
error: onError
});
Anyone know how I can force the "data" value to be sent in the body of the request?
In general, that's not how systems use GET requests. So, it will be hard to get your libraries to play along. In fact, the spec says that "If the request method is a case-sensitive match for GET or HEAD act as if data is null." So, I think you are out of luck unless the browser you are using doesn't respect that part of the spec.
You can probably setup an endpoint on your own server for a POST ajax request, then redirect that in your server code to a GET request with a body.
If you aren't absolutely tied to GET requests with the body being the data, you have two options.
POST with data: This is probably what you want. If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests.
GET with query string data: You can convert your data to query string parameters and pass them along to the server that way.
url: 'somesite.com/models/thing?ids=1,2,3'
we all know generally that for sending the data according to the http standards we generally use POST request.
But if you really want to use Get for sending the data in your scenario
I would suggest you to use the query-string or query-parameters.
1.GET use of Query string as.
{{url}}admin/recordings/some_id
here the some_id is mendatory parameter to send and can be used and req.params.some_id at server side.
2.GET use of query string as{{url}}admin/recordings?durationExact=34&isFavourite=true
here the durationExact ,isFavourite is optional strings to send and can be used and req.query.durationExact and req.query.isFavourite at server side.
3.GET Sending arrays
{{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]
and you can access those array values at server side like this
let osValues = JSON.parse(req.query.os);
if(osValues.length > 0)
{
for (let i=0; i<osValues.length; i++)
{
console.log(osValues[i])
//do whatever you want to do here
}
}
Just in case somebody ist still coming along this question:
There is a body query object in any request. You do not need to parse it yourself.
E.g. if you want to send an accessToken from a client with GET, you could do it like this:
const request = require('superagent');
request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
if (err) throw new Error(err);
console.log(res);
});
The server request object then looks like {request: { ... query: { accessToken: abcfed } ... } }
You know, I have a not so standard way around this. I typically use nextjs. I like to make things restful if at all possible. If I need to make a get request I instead use post and in the body I add a submethod parameter which is GET. At which point my server side handles it. I know it's still a post method technically but this makes the intention clear and I don't need to add any query parameters. Then the get method handles a get request using the data provided in the post method. Hopefully this helps. It's a bit of a side step around proper protocol but it does mean there's no crazy work around and the code on the server side can handle it without any problems. The first thing present in the server side is if(subMethod === "GET"){|DO WHATEVER YOU NEED|}
Using
$.getJSON();
or
$.post();
I'm trying to send some parameters through a page that is just for AJAX request
and get some results in JSON or html snippet.
What I want to know is that which one is faster?
Assume the HTML file would be simply plain boolean text (true or false)
As others said there is no real difference between the two functions, because both of them will be sent by XMLHttpRequest.
If the server is handling both of the requests with the same code then the handling times should be the same.
Therefore the question can be translated to which one is faster the HTTP GET request or the POST request?
Because the POST request needs two additional HTTP headers (Content-Type and Content-Length) comparing to the GET request the latter should be faster (because less data will be transferred).
But that's just the speed, I think it's better to follow the REST guidelines here. Use POST if you're modifying something, use GET if you want to fetch something.
And one another important thing, GET responses could be cached, but I was having problems caching POST ones.
i dont think it will make a difference both make use of ajax, .post loads the data using http post request where as getJSON uses a http get request more over you dont have to explicitly tell getJSON the dataType
If it is a HTTP action that is retrieving data from the server without persisting (updating) anything, GET is the correct semantic to use.
Both post and get use HTTP so performance difference will be negligible, especially considering the variables of WAN communication.
They are both wrappers/shorthand methods for jQuery.ajax, so there wont be a performance difference.
This is old but ...
We all have to remember about: CSRF/XSRF.
If you do it this way:
$.ajax({
type: "POST",
dataType: "json",
url: url,
data: {
token : 'pass-some-security-token-here'
},
cache: false,
success: function(data) {
//do your stuff here
}
});
you can receive it then like this, nullifying most CSRF/XSRF
if (isset($_POST['token'])) { //you can also test token further
//do your stuff her and send back result
} else {
//error: sorry, invalid, or no security token
}
In many cases GET is an invitation for bad guys, as getJSON uses GET HTTP request.
$.getJSON(); is a shortcut to $.ajax(); which also calls $.post(); so you won't see much difference (but it will be easier to use $.getJSON() directly).
See the jquery doc
[EDIT] NimChimpsky was faster than me...
There are no difference, Because both are using XMLHttpRequest.
First, $.getJSON() is a shorthand Ajax function, which is equivalent to:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
https://api.jquery.com/jQuery.getJSON/
Second, $.post() is also a shorthand Ajax function, which is equivalent to:
$.ajax({
type: "POST",
url: url,
data: data,
success: success,
dataType: dataType
});
https://api.jquery.com/jquery.post/