1. 程式人生 > >No ‘Access-Control-Allow-Origin’ header is present on the requested resource 報錯原因及解決方案

No ‘Access-Control-Allow-Origin’ header is present on the requested resource 報錯原因及解決方案

跨域——Cross-Origin Resource Sharing

跨域請求:簡單說,不同域名之間可以請求到資料的行為;

報錯資訊:

Failed to load https://example.com/: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://anfo.pl’ is therefore not allowed access. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

CORS是一種可以讓你實現跨站點請求並同時阻止惡意js的請求,它會在你傳送下面幾種HTTP請求時觸發:

這個機制阻止攻擊者在一些網站上放置js指令碼(比如通過Googls Ads展示的廣告)發起一個AJAX請求訪問www.yourbank.com,假設你剛好登陸過這個網站,就可能使用你的驗證資訊發起一筆轉賬。

如果你的瀏覽器發起一個“非簡單”請求(比如這個請求裡包含了cookies,或者Content-typeapplication/x-ww-form-urlencoded, multipart/form-data 或者 text-plain)一個叫做預檢查的機制會發送一個OPTIONS

請求到伺服器。如果伺服器沒有返回帶有特殊頭部的資料,簡單請求GET或者POST請求仍然會發送,伺服器的資料也會返回,但是瀏覽器會阻止Javascript獲取這次請求。

如果明確的需要在一個請求裡新增cookies,自定義頭部資訊或則其他特性,這將不在是一個簡單請求,並且伺服器沒有適當的返回,這次請求講不會發送。就是複雜請求時,如果OPTIONS的請求,伺服器沒有做出適當的返回,後面真實的請求將不會發送。

如何修復CORS“錯誤”?

你應該明白了CORS的行為並不是一個錯誤——它是一個機制,用來保護你的使用者,你和你請求的伺服器。

有時,缺乏適當的頭部資訊是因為客戶端實現錯誤(比如:丟失驗證資訊比如API key)。

下面有幾個適應不同情況,“修復這個錯誤”的方法:

A——我在開發前端並且可以控制或者認識開發後端的人員

這是一個最好的情況——你應該能讓返回資訊的頭裡包含適當的CORS欄位。如果你請求的API使用node的experss,你可以使用cors包。如果你想讓你的網站更加的安全,你應該使用白名單來返回Access-Control-Allow-Origin頭。

B——我在開發前端,但是我不能控制後端,我需要一個臨時方案

這是第二個最好的情況,特別是在有時間限制的情況裡。臨時的解決這個問題可以讓你的瀏覽器忽略CORS機制——比如安裝ACAO Chrmoe外掛或者啟動Chrome時輸入下面的指令:

chrome --disable-web-security --user-data-dir

**重要:**需要記住的是,這個方法會關閉整個瀏覽器的CORS機制,包含你瀏覽器正在訪問的網站,要小心使用,非常不安全。(譯者注:這個方法沒有用過,個人覺得風險太大,臨時測試也慎用,怕你開了外掛忘記關掉)

C——我在開發前端,但是我控制不了後端,而且將來也控制不了

好的。事情越來越複雜了。首先,你應該思考,為什麼伺服器沒有返回適當的頭部。

也許你請求的API不許允第三方應用請求它們?或者這些API僅僅給APP使用,而不是瀏覽器?或者你應該傳送一個驗證token在你請求的URL裡?

假如你堅持要通過瀏覽器獲得它們的資料,你應該自己寫一個代理,在瀏覽器和你要請求的API之間。就像我們在方法B裡做的那樣。

這個代理沒有執行在和你應用相同的域名下,但是這個代理為你的請求提供正確的CORS響應。這個代理去請求API時就不需要CORS支援,因為這個代理不是用瀏覽器去訪問的API,而是通過程式直接發起的請求。

請記住,如果你想支援使用者驗證,這些方法會引入安全風險。

譯者注:實戰中,能控制伺服器的情況下。最好是伺服器上正確配置CORS,可以在伺服器API層進行配置,也可以在nginx或者apache層進行配置(這樣後端新加伺服器不用再配置)。最好配置上白名單。真實專案中,CORS問題主要出現在開發階段,本地啟動的前端開發伺服器域名是localhost。除錯介面可能是一個其他域名,這個時候的解決方法。AC都可以,不過C方法會導致每個前端專案都需要自己的開發伺服器支援一個proxy。個人偏向去測試環境的nginx服務層配置跨域,這樣,開發環境統一支援前端本地開發跨域除錯介面。