I have been using the esri.request to make get calls for a while and it's worked great:
request = Request({url: url, handleAs: 'json'});
Now I have a requirement to be able to post JSON data and get a similar response. From the API reference I thought it would be as simple as:
request = Request({url: url, handleAs: 'json', callbackParamName: 'callback', content: params}, {usePost: 'true'});
But I was getting a 415 error from the REST endpoint I was hitting.
I looked at the developer tools, Network section, and I saw that under Params, the payload was of type Form data. I think it needs to be JSON format. I looked under Headers and Content-Type is "application/x-www-form-urlencoded".
So I found the setRequestPreCallback function and started using that to set the headers["Content-Type"] = "application/json". That seemed to work because I can see Content-Type is now "application/json". However, my 415 error changed to a 400 error. If I look under Params it is not type JSON like I expect. It just says Request payload and the data looks like a string with = and & instead of a JSON format.
Is there something else you have to do to make the data post as JSON?
Try { ..., content:JSON.stringify(params), ... }
It may be interpreting your params as FormData or something along those lines.
Yeah, I did try that, and under Params it still says Request payload and the value looks like:
0=%7B&1=%22&2=s&3=y&4=s&5=_&6=a&7=s&8....
I even tried to just hard code the content like:
request = Request({url: url, handleAs: 'json', callbackParamName: 'callback', content: {username: "test", role: "user"}}, {usePost: 'true'});
And I still get a Request payload that looks like:
username=test&role=user
Have you tried JSON.stringify on the individual JSON-format parameters in the request content? And also throw in a f: "json" in the content.
Do you mean like this?
request = Request({url: url, handleAs: 'json', callbackParamName: 'callback', content: {f: "json", username: JSON.stringify("test"), role: JSON.stringify("user")}}, {usePost: 'true'});
That creates a Request payload of:
f=json&username=%22test%22&role=%22user%22
It still doesn't look like JSON and still gives status 400.
Yes that's the idea, but only for more complex content parameters that are also JSON objects. Why not try the request with a jQuery Ajax or standard XMLHttpRequest instead?
Yeah, that's what I am doing for now. The $.ajax works as expected. I just wanted to use pure esri if I could. It seems like something that is supposed to work and I am just missing something. Thanks.
In the Network tab, can you see if the request is being made as GET or POST? If it still uses GET, one suggestion is to try using a boolean instead of a string for the 'usePost' parameter. It also helps if you have a JSBin or similar so we can see the code and issue in action.
{usePost:true}
I would also like to see how the esri.request compares to the jQuery Ajax request.
Look at the code under the folder named "editors" of the ESRI's geoprocessing widget. You will see how they handle post with url or files (csv, shapefiles)....