問題描述
我正在通過 POST 請求跨域發送數據,但響應不起作用,具體來說,jQuery 的成功處理程序永遠不會被調用.
I'm sending data cross domain via a POST request but the response isn't working, specifically, jQuery's success handler never gets called.
使用的東西:Django、Apache、jQuery.
Stuff being used: Django, Apache, jQuery.
所以,我設置了一個與此類似的請求:
So, I set up a request rather similar to this:
$.ajax({
url: "http://somesite.com/someplace",
type: "POST",
cache: false,
dataType: "json",
data: { ... },
success: function( msg ) {
alert(msg);
},
});
眾所周知,CORS 允許我回復 OPTIONS
適當地查詢說是的,你可以發帖給我".我正在做的.Firebug 確認我收到了我的 200
狀態代碼,并且返回類型實際上是 application/json
.但是,Firebug 也確認上面的成功處理程序沒有被調用.
As you well know, CORS allows me to respond to an OPTIONS
query appropriately to say "Yes, you can POST to me". Which I'm doing. Firebug confirms I'm getting my 200
status code and that the return type is in fact application/json
. However, Firebug also confirms that the success handler in the above is not being called.
作為參考,我對 OPTIONS
的回復是:
For reference, my response to OPTIONS
is:
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
相比之下,如果我設置一個 complete: function()...
處理程序,它就可以工作.
In contrast, if I set up a complete: function()...
handler it works.
所以,問題是:發生了什么(或沒有發生),為什么?我得到的數據很好,我只想能夠返回響應.
So, question is: what's happening (or not) and why? I am getting data fine, I'd just like to be able to return the response.
更新:這解決了我在某些瀏覽器上的問題,但由于我對此行為沒有完整的明確解釋,所以我將其保持打開狀態.
好的,所以我閱讀了手冊以及我對它的理解,算法應用的大致是這樣的:
Ok, so I read the manual and what I understand of it, the algorithm applied is roughly this:
- 用戶代理可以實現預檢調用.這是
OPTIONS
請求.這個想法是他們提出這個請求,這給他們一個關于所請求資源的答案,然后他們應該緩存這些資源.我沒有傳回 max-age 字段,所以我懷疑在返回成功并且允許 X 請求時,用戶代理的緩存中沒有任何內容允許我這樣做,所以應用默認規則(隔離請求). - 當您發出實際請求時,我相信用戶代理應該檢查飛行前緩存的權限.如果沒有我的 max-age 字段,我相信它找不到這些權限.但是,在
POST
上使用相同的標頭進行響應似乎允許 Firefox 和 Google Chrome 查看響應.歌劇不能.IE 目前尚未經過測試.
- User agents may implement a preflight call. This is the
OPTIONS
request. The idea is that they make this request which gives them an answer with respect to the requested resource, which they are then supposed to cache. I'm not passing back a max-age field, so I suspect whilst success is being returned and the X-request allowed, there is nothing in the user agent's cache which permitted me to make it, so the default rules (isolate the request) are applied. - When you make the actual request, I believe the user agent is supposed to inspect the pre-flight cache for permissions. Without my max-age field, I believe it isn't finding these permissions. However, responding with the same headers on
POST
appears to allow Firefox and Google Chrome to view the response. Opera can not. IE remains untested at the moment.
我目前不明白,從手冊中也不清楚(至少對我而言)CORS 請求是否也應該在請求中使用這些標頭以及 OPTIONS
來回答.我將試驗 Max-Age
標頭并查看允許或不允許的內容.但是,我對這個問題仍然缺乏一定的權威理解,所以如果這里有人知道,我會全力以赴.
I do not currently understand and it is not clear from the manual (to me at least) whether a CORS request should also answer with these headers in the request as well as the OPTIONS
. I shall experiment with the Max-Age
header and see what that allows or does not allow. However, I'm still short of some definite authoritative understanding on the issue so if there is someone on here who knows, I'm all ears.
推薦答案
好吧,所以我相信正確的做事方式是這樣的:
Ok, so I believe the correct way to do things is this:
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()
這是基于我從 Mozilla 挖掘的關于預檢請求的文檔.
This is based on the documentation I dug up from Mozilla on preflighted requests.
所以,我相信會發生這樣的事情:
So, what I believe will happen is this:
- 如果預檢緩存中沒有任何內容,則發送
OPTIONS
并將X-Requested-With
設置為XMLHttpRequest
我相信這是必要的允許 Javascript 訪問任何內容,以及Origin
標頭. - 服務器可以檢查該信息.這就是 CORS 的安全性.就我而言,我的回應是任何來源都可以"和你可以發送
X-Requested-With
東西".我是說OPTIONS
和POST
是允許的,并且這個響應應該被緩存 30 分鐘. - 然后客戶端繼續進行 POST,這在之前是有效的.
- 我最初修改了響應以包含
Allow-Methods
和Allow-Headers
但根據上述鏈接文檔中的交換,這不是必需的.這是有道理的,訪問檢查已經完成. - 我相信會發生此處描述的資源共享檢查.基本上,一旦提出了上述請求,瀏覽器就會再次檢查
Allow-Origin
字段的有效性,這在諸如POST
之類的請求上.如果通過,客戶端可以訪問數據,如果沒有,則請求已經完成,但瀏覽器拒絕實際的客戶端應用程序 (Javascript) 訪問該數據.
- If there's nothing in the preflight cache,
OPTIONS
is sent withX-Requested-With
set toXMLHttpRequest
I believe this is necessary to allow Javascript access to anything, along with anOrigin
header. - The server can examine that information. That is the security of CORS. In my case, I'm responding with "any origin will do" and "you're allowed to send the
X-Requested-With
thing". I'm saying thatOPTIONS
andPOST
are allowed and that this response should be cached for 30 mins. - The client then goes ahead and makes the POST, which was working before.
- I modified the response originally to include
Allow-Methods
andAllow-Headers
but according to the exchange in the above linked documentation this isn't needed. This makes sense, the access check has already been done. - I believe then that what happens is the resource sharing check described here. Basically, once said request has been made, the browser again checks the
Allow-Origin
field for validity, this being on the request such asPOST
. If this passes, the client can have access to the data, if not, the request has already completed but the browser denies the actual client side application (Javascript) access to that data.
我相信這是對正在發生的事情的正確總結,并且無論如何它似乎有效.如果我說的不對,請大聲疾呼.
I believe that is a correct summary of what is going on and in any case it appears to work. If I'm not right, please shout.
這篇關于使用跨域資源共享的跨域 POST 查詢沒有返回數據的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!