开发者

Ajax POST and Django Tastypie

开发者 https://www.devze.com 2023-03-30 09:44 出处:网络
curl --dump-header - -H \"Content-Type: application/json\" -X POST --data \'{\"latlong\": \"test\"}\' http://localhost:8000/geo/api/geolocation/
curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"latlong": "test"}' http://localhost:8000/geo/api/geolocation/

The above works fine but when I try to replicate the POST in the ajax below I get 500 error.

$.ajax({
  type: 'POST',
  url: 'http://localhost:8000/geo/api/geolocation/',
  data: '{"latlong": "test"}',
  success: latlongSaved(),
  dataType: "application/json",
  processData:  false,
});

Error message is:

{"error_message": "The format indicated 'application/x-www-form-urlencoded' had no available deserialization method. Please check your ``formats`` and ``content_types`` on your Serializer." .... }

Worth noting this is cross domain and I'm using the django-crossd开发者_高级运维omainxhr-middleware.py found via git:gist

If I add a content type to the ajax call like this:

contentType: "application/json"

I get this error back:

XMLHttpRequest cannot load http://localhost:8000/geo/api/geolocation/. Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
Request URL:http://localhost:8000/geo/api/geolocation/
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Access-Control-Request-Headers:Origin, Content-Type, Accept
Access-Control-Request-Method:POST
Origin:http://localhost:3000
Response Headersview source
Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE
Access-Control-Allow-Origin:*
Content-Type:text/html; charset=utf-8
Date:Tue, 23 Aug 2011 07:59:49 GMT
Server:WSGIServer/0.1 Python/2.6.1


You are explicitly declaring your content type in your call to curl, but you are not being specific on your jQuery.ajax() call.

Update your JavaScript to define exactly what the content type is going to be:

$.ajax({
  type: 'POST',
  url: 'http://localhost:8000/geo/api/geolocation/',
  data: '{"latlong": "test"}',
  success: latlongSaved(),
  dataType: "application/json",
  processData:  false,
  contentType: "application/json"
});


I added XS_SHARING_ALLOWED_HEADERS to the middleware and that solved the problem.

https://gist.github.com/1164697


Add XsSharing (https://gist.github.com/1164697) to settings.py:

MIDDLEWARE_CLASSES = [
    ...,
    'django-crossdomainxhr-middleware.XsSharing'
]

Then use the following javascript to make an ajax call:

$.ajax({
  type: 'POST',
  url: 'http://localhost:8000/geo/api/geolocation/',
  data: '{"latlong": "test"}',
  success: latlongSaved(),
  contentType:'application/json',
  dataType: 'application/json',
  processData: false,
});

Notice that data must be a well-formed JSON string, otherwise jQuery will silently ignore the ajax call and do nothing.

What's behind the scenes is that the ajax call will firstly send out OPTIONS /geo/api/geolocation/. Because the response header is modified by XsSharing middleware, jQuery will issue another POST /geo/api/geolocation request that does the actual creation.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号