Flask can't handle json data in ajax GET request - javascript

I try to send jQuery AJAX request to my flask server :
$.ajax({
type: 'GET',
url: '/get',
dataType: "json",
contentType:"application/json",
data: JSON.stringify({ subject : "gpu",
filter : {
ids: [2, 3]
}
}),
success: function (data) {
console.debug(data);
}
});
And then I wait for a response from the server. Server part looks like this:
#api.route('/get', methods=['GET'])
def get():
response = None
try:
data = request.get_json()
response = do_some_magic(data)
except Exception as e:
respond = {'state': 'error', 'data': e.message}
finally:
return json.dumps(respond)
So, this combination doesn't work. request has only args field = ImmutableMultiDict([('{"subject":"gpu","filter":{"ids":[2,3]}}', u'')]) and json field = None.
But when in ajax request I set type: 'GET' and in flask get method methods=['GET'], server starts to handle requests correctly.
So, it would not be a real issue, but then I tried to send a GET request with postman utility. It's request:
GET /get HTTP/1.1
Host: localhost:5000
Content-Type: application/json
cache-control: no-cache
Postman-Token: 1d94d81c-7d93-4cf6-865a-b8e3e28278c1
{
"subject": "gpu",
"filter": {
"ids": [
2,
3
]
}
}------WebKitFormBoundary7MA4YWxkTrZu0gW--
And flask code worked with methods=['GET']. So the question is, what can cause such behaviour?

From jQuery documentation
data
Type: PlainObject or String or Array
Data to be sent to the server.
It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below).
If processData is set to false, it means that the data string is still appended to the URL, just without some processing.
This may be due to the behaviour of XMLHttpRequest.send()
send() accepts an optional parameter which lets you specify the request's body; this is primarily used for requests such as PUT. If the request method is GET or HEAD, the body parameter is ignored and the request body is set to null.

Related

How to request data from an API using AJAX.

I want to make a post request to an API (http://nairabox.com/food_documentation/) using Ajax but am kind of confused on how to go about it.
This is what I have tried so far:
$.ajax({
type: "POST",
url: "https://mapp.nairabox.com:8443/api/v1/food/",
dataType : "json",
data: { case: "browse"},
headers: {
'case': 'browse'
},
success: function(data){
console.log('success');
}
})
So far, it is returning no result.
What could I be getting wrong?
The API doc is here (http://nairabox.com/food_documentation/)
The documentation you link to does not say to add any custom HTTP request headers.
You, however, are doing so here:
headers: {
'case': 'browse'
},
The case data belongs in the data and only in the data.
By adding the custom header, you are preventing the request from being simple and triggering a preflight OPTIONS request which the server does not accept.
Remove the above and you will get a response (and your success function will fire … you should probably do something with the data argument though)
Note, also, that the documentation says you should pass latitude and longitude as well as case.
Unless you add them, the response you get is unlikely to be useful.

POST data to a Google form with AJAX

I am trying to post data to a from AJAX to a Google form, but even though it reports success with a statusCode of 0, the data never appears in the form:
var dat={ "entry.529474552" :"data1", "entry.1066559787": "name1"};
postToGoogle("1FAIpQLSf4w1OQGsIncaiqXlmfAl4jYSt-e4Zx3xVJa7Weob4LnQbRZQ",dat);
function postToGoogle(id, dat) {
$.ajax({
beforeSend: function (xhr) {
xhr.setRequestHeader('Access-Control-Allow-Origin', 'chrome-extension://EXTENSION_ID');
xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET, POST, PUT');
},
url: "https://docs.google.com/forms/d/e/"+id+"/formResponse",
data: dat,
type: "POST",
dataType: "xml",
xhrFields: { withCredentials: true },
statusCode: {
0: function() { console.log("OK") },
200: function() { console.log("error") },
}
});
}
It generates a CORS error, but supposedly, the POST should go through anyway.
For those looking to do this as of April 2019
I was working on this today. The current answer is as follows:
Each field in the Google Form has a unique ID. In order to retrieve it, get a pre-filled link by filling out all relevant form fields you wish to programatically submit
Note: In order to ensure the URL is accessible without restriction, you'll also want to disable restriction to your domain only (for GSuite paying users)
Then, copy the link and paste in your browser. The URL has a base format as follows:
https://docs.google.com/forms/d/e/[FORMID]/formResponse
Each param is a key/value pair of type: entry.XXXXXX=value
The prefilled link will give you the value of XXXXX for each relevant field
Request must be made with following headers:
Method: GET
Content-Type: application/x-www-form-urlencoded
The final request looks like this
https://docs.google.com/forms/d/e/123332233bsj333/formResponse?entry.123456=value1&entry.2333442=value2&submit=Submit
Don't forget to append submit=Submit at the end of your request!
It generates a CORS error, but supposedly, the POST should go through anyway.
While it is possible to make a successful POST request, get a CORS error, and be unable to read the response, this is only true for Simple Requests.
Because your request has:
Custom headers (Access-Control-Allow-Origin and Access-Control-Allow-Methods, which are response headers and have no business being on a request in the first place)
Credentials (i.e. you have set withCredentials: true)
… it is a Preflighted Request.
Before the browser will make the POST request, it will make an OPTIONS request to ask permission.
Since it doesn't get permission, the request fails.
Note that even if you did turn it into a simple request and make the POST successfully, you would still get a status of 0. You can't read the status when there is a CORS error.

$.ajax post request not sending data parameters to server

I am running into problem requesting data from an API. The documentation states that I must make a post request. My goal is to make the request with jQuery, then style the resulting data.
Since I'm using a Cross-Domain-Request, I know that I have to use jsonp. The issue is that I get parseerror when I run this code because the server is returning an XML error. (The server defaults to an xml response if no format is specified)
$.ajax({
type: 'POST',
url: url,
data: {format: 'json'},
dataType: 'jsonp',
success: function(data) {
console.log("Success.");
},
error: function(data, error, err) {
console.log(data.status);
console.log(error);
console.log(err);
}
});
Inside the inspector I see:
Uncaught SyntaxError: Unexpected token <
menu?&callback=jQuery2240569993828256961_1469752734662&format=json&_=1469752734663:1
This is the XML response...
<?xml version="1.0" encoding="UTF-8"?><response> <response_header> <response_code>ERROR</response_code>
</response_header>
<response_details> <error_details>The post parameters contain an invalid or disabled API ID</error_details>
</response_details>
</response>
Because it returns XML, I can determine that the server is not even recognizing my parameter {format: 'json'}, because here is the same request in Python:
from urllib.parse import urlencode
from urllib.request import Request, urlopen
url = url # Set destination URL here
post_fields = {'format':'json'} # Set POST fields here
request = Request(url, urlencode(post_fields).encode())
json = urlopen(request).read().decode()
print(json)
And the resulting JSON response:
{"response_header":{"response_code":"ERROR"},"response_details":{"error_details":"The post parameters contain an invalid or disabled API ID"}}
As you can see, it responds with JSON demonstrating that the server read the post request.
For some reason, the AJAX request is not sending the parameters through which means I can't even get back the actual data I need by including the api key + api id.
Can anyone tell me what is going on here?
Thank you.

How to set the raw body in jQuery Ajax?

Instead of sending a list of key/value pairs, I need to send a JSON string as the body of the POST request.
I make this POST request using jQuery's $.ajax function.
How do I set it correctly?
When I say JSON string, I mean something like: {action:'x',params:['a','b','c']} .
This is how I would use this JSON string in PHP on the server:
var_dump(json_decode(file_get_contents('php://input')));
Results in:
stdClass Object
action = x
params = Array
(
0 = a
1 = b
2 = c
)
Try:
$.ajax('url',{
'data': JSON.stringify(yourJSONObject), //{action:'x',params:['a','b','c']}
'type': 'POST',
'processData': false,
'contentType': 'application/json' //typically 'application/x-www-form-urlencoded', but the service you are calling may expect 'text/json'... check with the service to see what they expect as content-type in the HTTP header.
});
if you dont specify the key i think it will post as the body without the key like
$.ajax({
data:JSON.stringify({action:'x',params:['a','b','c']})
});

GET ajax request

I'm sending GET request (which returns JSON).
The code looks like:
$.ajax({
url: "http://www.new.marketprice.ru/retrieveRegions.html",
dataType: "jsonp",
data: {
searchStr: request.term
},
error: function() {
console.log('epic fail');
},
success: function( data ) {
console.log(data);
}
});
It returns (into console);
Resource interpreted as Other but transferred with MIME type undefined.
epic fail
But in Network tab I see GET request with returned data:
[
{ "region":"Московская область","countryId":1,
"cityId":23,"regionId":12345,"city":"Москва","country":"Россия"},
{"region":"Ленинградская область","countryId":1,"cityId":453,
"regionId":54321,"city":"Санкт Петербург","country":"Россия"}
]
Why does error callback is called?
UPD
Okay, I set json and now no warning but error:
XMLHttpRequest cannot load http://www.new.marketprice.ru/retrieveRegions.html?searchStr=test. Origin http://new.marketprice.ru is not allowed by Access-Control-Allow-Origin
It's so strange because running script is located at same domain :(
It is only a json response not JSONP. Generally for JSONP the request will have callback method and response will be wrapped in that function name
Your headers don't specify the correct mime-type (application/json-p) and jQuery(?) is confused because it's not sure if it should process it as json or not.
See if you can get your server to respond with the correct type. The appropriate header is called Content-Type.
EDIT: whoops, and the OP is right, its not even JSON-P. Try changing what jquery is expecing to just 'json' first.
i was also in problem like this just try by using one more argument callback=? or json=jsonp

Categories