8
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
4

3 回答 3

7

您在对 的调用中明确声明了您的内容类型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"
});
于 2011-08-22T21:43:00.387 回答
3

我在中间件中添加了 XS_SHARING_ALLOWED_HEADERS 并解决了问题。

https://gist.github.com/1164697

于 2011-08-23T08:56:38.257 回答
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请求来进行实际的创建。

于 2012-02-21T14:56:58.460 回答