Ajax POST 和 Django Tastypie
Posted
技术标签:
【中文标题】Ajax POST 和 Django Tastypie【英文标题】:Ajax POST and Django Tastypie 【发布时间】:2011-11-01 07:13:16 【问题描述】:curl --dump-header - -H "Content-Type: application/json" -X POST --data '"latlong": "test"' http://localhost:8000/geo/api/geolocation/
上面的工作正常,但是当我尝试在下面的 ajax 中复制 POST 时,我得到 500 错误。
$.ajax(
type: 'POST',
url: 'http://localhost:8000/geo/api/geolocation/',
data: '"latlong": "test"',
success: latlongSaved(),
dataType: "application/json",
processData: false,
);
错误信息是:
"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." ....
值得注意的是这是跨域,我使用的是通过 git:gist 找到的 django-crossdomainxhr-middleware.py
如果我像这样向 ajax 调用添加内容类型:
contentType: "application/json"
我得到了这个错误:
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
【问题讨论】:
查看文档 - 您可能需要在 url 字符串中设置 json 选项。 你能发布curl
请求头和jQuery头之间的差异吗?您可以在 Firebug 的控制台选项卡中看到 jQuery 标头。
【参考方案1】:
您在对curl
的调用中明确声明了您的内容类型,但您并未具体说明您的jQuery.ajax()
调用。
更新您的 javascript 以准确定义内容类型:
$.ajax(
type: 'POST',
url: 'http://localhost:8000/geo/api/geolocation/',
data: '"latlong": "test"',
success: latlongSaved(),
dataType: "application/json",
processData: false,
contentType: "application/json"
);
【讨论】:
为了清楚起见,您能否提及dataType
的作用?
您正在执行跨域 AJAX 调用。这不适用于 JSON,您必须使用 JSONP
dataType
告诉 jQuery 你希望服务器返回什么类型的数据。【参考方案2】:
我在中间件中添加了 XS_SHARING_ALLOWED_HEADERS 并解决了问题。
https://gist.github.com/1164697
【讨论】:
【参考方案3】:将 XsSharing (https://gist.github.com/1164697) 添加到 settings.py:
MIDDLEWARE_CLASSES = [
...,
'django-crossdomainxhr-middleware.XsSharing'
]
然后使用以下 javascript 进行 ajax 调用:
$.ajax(
type: 'POST',
url: 'http://localhost:8000/geo/api/geolocation/',
data: '"latlong": "test"',
success: latlongSaved(),
contentType:'application/json',
dataType: 'application/json',
processData: false,
);
注意data
必须是格式正确的JSON字符串,否则jQuery会默默地忽略ajax调用,什么也不做。
幕后是ajax调用会先发出OPTIONS /geo/api/geolocation/
。因为响应头是由 XsSharing 中间件修改的,所以 jQuery 会发出另一个 POST /geo/api/geolocation
请求来进行实际的创建。
【讨论】:
这个:“注意数据必须是格式正确的 JSON 字符串,否则 jQuery 会默默地忽略 ajax 调用,什么也不做”,对我帮助很大!谢谢以上是关于Ajax POST 和 Django Tastypie的主要内容,如果未能解决你的问题,请参考以下文章