使用跨源资源共享的跨域POST查询不会返回任何数据

13 javascript ajax jquery cross-domain cors

我通过POST请求发送数据跨域但响应不起作用,具体来说,jQuery的成功处理程序永远不会被调用.

正在使用的东西:Django,Apache,jQuery.

所以,我设置了一个与此类似的请求:

$.ajax({
    url: "http://somesite.com/someplace",
    type: "POST",
    cache: false,
    dataType: "json",
    data: { ... },
    success: function( msg ) {
        alert(msg);
    },
});
Run Code Online (Sandbox Code Playgroud)

众所周知,CORS允许我OPTIONS适当地回答查询,说"是的,你可以发帖给我".我在做什么 Firebug确认我正在获取我的200状态代码并且返回类型实际上是application/json.但是,Firebug还确认上面的成功处理程序没有被调用.

作为参考,我的回答OPTIONS是:

elif request.method == "OPTIONS":
    response = HttpResponse("")
    response['Access-Control-Allow-Origin'] = "*"
    response['Access-Control-Allow-Methods'] = "POST, GET, OPTIONS"
    response['Access-Control-Allow-Headers'] = "X-Requested-With"
    return response
Run Code Online (Sandbox Code Playgroud)

相反,如果我设置了一个complete: function()...处理程序,它就可以了.

所以,问题是:发生了什么(或不发生)以及为什么?我收到的数据很好,我只想回复一下.


更新:这解决了我在某些浏览器上的问题,但由于我对此行为没有完全明确的解释,我将其保持打开状态.

好的,所以我阅读了手册以及我对它的理解,所应用的算法大致如下:

  1. 用户代理可以实现预检调用.这是OPTIONS请求.他们的想法是,他们提出这个请求,让他们得到一个关于所请求资源的答案,然后他们应该缓存这些资源.我没有传回一个max-age字段,所以我怀疑在返回成功并且X-request允许的情况下,用户代理的缓存中没有任何内容允许我创建它,因此默认规则(隔离请求) )应用.
  2. 当你提出实际请求时,我相信用户代理应该检查飞行前缓存的权限.没有我的max-age字段,我相信它没有找到这些权限.但是,使用相同的标题响应POST似乎允许Firefox和Google Chrome查看响应.歌剧不能.IE目前仍未经过测试.

我目前不理解,并且从手册(至少对我来说)中不清楚CORS请求是否也应该在请求中回答这些标题以及OPTIONS.我将试验Max-Age标题,看看允许或不允许的内容.但是,我仍然缺乏对这个问题的一些明确的权威性理解,所以如果有人在这里知道,我全都听见了.

小智 17

好的,所以我相信正确的做事方式是这样的:

if request.method == "POST":
    response = HttpResponse(simplejson.dumps(data),mimetype='application/json')
    response['Access-Control-Allow-Origin'] = "*"
    return response
elif request.method == "OPTIONS":
    response = HttpResponse("")
    response['Access-Control-Allow-Origin'] = "*"
    response['Access-Control-Allow-Methods'] = "POST, OPTIONS"
    response['Access-Control-Allow-Headers'] = "X-Requested-With"
    response['Access-Control-Max-Age'] = "1800"
else:
    return HttpResponseBadRequest()
Run Code Online (Sandbox Code Playgroud)

这是基于我在Mozilla上根据预先请求挖出文档.

那么,我相信会发生的是:

  1. 如果预检高速缓存中没有任何内容,OPTIONS则发送X-Requested-With设置为" XMLHttpRequest我认为这是必要的,以允许Javascript访问任何内容,以及Origin标题.
  2. 服务器可以检查该信息.这是CORS的安全性.在我的情况下,我回答"任何来源都会做"和"你被允许发送的X-Requested-With东西".我说的是,OPTIONS并且POST被允许,这个响应应该缓存30分钟.
  3. 然后客户端继续进行POST,之前正在运行.
  4. 我修改的响应本来以包括Allow-MethodsAllow-Headers但根据上述链接的文档,这是不需要在交换.这是有道理的,访问检查已经完成.
  5. 我相信那里发生的是这里描述资源共享检查.基本上,一旦提出请求,浏览器就会再次检查Allow-Origin字段的有效性,这是在请求上,例如POST.如果这通过,客户端可以访问数据,如果没有,请求已经完成,但浏览器拒绝实际的客户端应用程序(Javascript)访问该数据.

我相信这是对正在发生的事情的正确总结,无论如何它似乎都有效.如果我不对,请大声喊叫.