2017-01-16 51 views
3

我的FE的應用程序使用API​​從不同域發送。我知道它應該觸發CORS,但據我瞭解,它不應該爲每個請求創建預檢。預檢請求與所有方法

docs,我不應該有GET方法預檢要求。

Cross-site requests are preflighted like this since they may have implications to 
user data. In particular, a request is preflighted if: 

    - It uses methods other than GET, HEAD or POST. 
Also, if POST is used to send request data with a Content-Type 
other than application/x-www-form-urlencoded, multipart/form-data, 
or text/plain, e.g. if the POST request sends an XML payload to the 
server using application/xml or text/xml, then the request is preflighted. 
    - It sets custom headers in the request 
(e.g. the request uses a header such as X-PINGOTHER) 

但是,我要送每一個要求,具有預檢(期權)的要求,不管它是GET或POST,我覺得很奇怪(按照什麼文檔說的)。

我設置一些標題(和我與withCredentials: true發送),但我不認爲它應該是這個問題:

headers.append('Access-Control-Allow-Origin', FRONTEND_URL); 
    headers.append('Accept', 'application/json'); 
    headers.append('Content-Type', 'application/json'); 
    headers.append('Authorization', this._generateApiKey()); 
    headers.append('Language', this._languageISOCode); 

我這麼想嗎?

+1

WithCredentials是你的自定義頭,這意味着它被用於預檢GET/POST請求 – Icepickle

回答

2

參見https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests

即使對於GET請求,用於以簡單的請求Content-Type頭的唯一的允許值是application/x-www-form-urlencodedmultipart/form-data,和text/plain。任何其他Content-Type值都會觸發瀏覽器進行預檢。

從事實中獲取規範(定義CORS行爲)這是繼指定它稱之爲CORS-safelisted request-header,將其定義爲一個:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type和其值,一旦解析,具有MIME類型(忽略參數)是application/x-www-form-urlencodedmultipart/form-data,或text/plain

任何請求,包括任何GET請求包含一個報頭,這不是一個CORS-safelisted請求頭觸發預檢。


爲了讓這一切更加清晰,我更新the MDN documentation about CORS 「simple requests」the MDN documentation about CORS preflighted requests(它是略高於什麼上述比較複雜,實際上,但什麼是上面這個問題的情況下就足夠了)。


注意的WebKit/Safari瀏覽器上放置允許在AcceptAccept-LanguageContent-Language頭值的額外限制。

如果任何這些頭有「非標」的價值觀,WebKit的/ Safari瀏覽器會做一個預檢。

至於什麼樣的WebKit/Safari瀏覽器認爲對於那些頭「非標準」的價值觀,這不是真正記錄除了以下的WebKit錯誤:

沒有其他瀏覽器實現這些額外的限制,因爲它們不是規範的一部分。他們被單方面添加到WebKit中,沒有與spec編輯器或其他瀏覽器進行任何討論。

+0

_that不是一個CORS-safelisted請求header_ - 你的意思是不是在4頭顯示出你的名單? –

+0

是的,任何不在上面4個標題列表中的標題。 – sideshowbarker

0

當應用程序駐留在一個域中,Web服務託管在不同的域上並且我們試圖進行Ajax調用以獲取響應時,通常會出現跨域問題。 對我們Web服務的Ajax調用以CORS錯誤結束。調用的HTTP方法是OPTIONS,而不是GET或POST。

解決這個問題是一個方面,但我們仍然需要保留安全認證。否則,我們最終會暴露一個威脅的未經認證的Web服務。

if (request.getMethod().equals("OPTIONS") && request.getHeader(ORIGIN).equals(FRONTEND_URL)) 
{ 
response.setHeader("Access-Control-Allow-Origin", FRONTEND_URL); 
response.setHeader("Access-Control-Allow-Credentials", "true"); 
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, HEAD"); 
response.setHeader("Access-Control-Allow-Headers",request.getHeader("Access-Control-Request-Headers")); 
}