ajax跨域方案 弄懂CORS

2021-09-25 02:56:41 字數 3222 閱讀 8802

如果你在前端使用過ajax,你應該對下面出現在瀏覽器控制台裡的錯誤很熟悉。如果你沒見過,那只能說明你還年輕。

如果你看到這個錯誤資訊,這表示這次返回資料失敗了,但是你仍然可以開啟瀏覽器的network欄,看到返回的資料——這到底是怎麼回事?

上面的錯誤是因為瀏覽器的cors機制導致的。cosr(跨站點資源分享)通俗的講是跨域問題,嚴格來說它是跨域問題的解決方案之一,而且是官方解決方案。

在cors成為標準之前,是沒有辦法請求不同網域名稱的後端api的,因為安全原因。請求會被同源策略阻止,現在也是。

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

- 不同的網域名稱 (比如在** example.com 請求 api.com)

- 不同的子網域名稱 (比如在** example.com 請求 api.example.com)

- 不同的埠 (比如在** example.com 請求 example.com:3001)

- 不同協議 (比如在** 請求

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

如果你的瀏覽器發起乙個「非簡單」請求(比如這個請求裡包含了cookies,或者content-type不包含如果明確的需要在乙個請求裡新增cookies,自定義頭部資訊或則其他特性,這將不在是乙個簡單請求,並且伺服器沒有適當的返回,這次請求講不會傳送。就是複雜請求時,如果options的請求,伺服器沒有做出適當的返回,後面真實的請求將不會傳送。

cors使用一些http頭資訊——包括請求和返回——為了讓工作繼續開展下去,你必須了解一下的一些頭資訊:

這個頭部資訊由伺服器返回,用來明確指定那些客戶端的網域名稱允許訪問這個資源。它的值可以是:

- * —— 允許任意網域名稱

- 乙個完整的網域名稱名字(比如:)

如果你需要客戶端傳遞驗證資訊到頭部(比如:cookies)。這個值不能為 * —— 必須為完整的網域名稱(這點很重要)。

這個頭部資訊只會在伺服器支援通過cookies傳遞驗證資訊的返回資料裡。它的值只有乙個就是 true。跨站點帶驗證資訊時,伺服器必須要爭取設定這個值,伺服器才能獲取到使用者的cookie。

提供乙個逗號分隔的列表表示伺服器支援的請求資料型別。假如你使用自定義頭部(比如:x-authentication-token 伺服器需要在返回options請求時,要把這個值放到這個頭部裡,否則請求會被阻止)。

相似的,這個返回資訊裡包含了一組頭部資訊,這些資訊表示那些客戶端可以使用。其他沒有在裡面的頭部資訊將會被限制(譯者注:這個頭資訊實戰中使用較少)。

乙個逗號分隔的列表,表明伺服器支援的請求型別(比如:get, post)

這個頭部資訊,屬於請求資料的一部分。這個值表明這個請求是從瀏覽器開啟的哪個網域名稱下發出的。出於安全原因,瀏覽器不允許你修改這個值。

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

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

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

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

這是乙個最好的情況——你應該能讓返回資訊的頭里包含適當的cors欄位。如果你請求的api使用node的experss,你可以使用cors包。如果你想讓你的**更加的安全,你應該使用白名單來返回access-control-allow-origin頭。

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

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

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

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

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

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

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

在中間加乙個**

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

你可以根據你的平台實現這個**,或者使用已經做好的解決方案,比如:

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

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

推薦乙個模擬介面的應用,可以在你本地開發前端,但是後端你不能直接訪問或者還沒寫好時,模擬除錯你的介面

AJAX 跨域解決方案 CORS

什麼是ajax?ajax 是無需重新整理頁面就能夠從伺服器去的資料的一種方法,負責ajax運作的核心物件是xmlhttprequest xhr 物件。同源策略是對xhr的乙個主要約束,它為通訊設定了 相同的域 相同的埠 相同的協議 這一限制。試圖訪問上述限制之外的資源都會引發安全錯誤,除非採用被認可...

Ajax跨域請求 CORS

ajax跨域請求 cors cors,又稱跨域資源共享,英文全稱cross origin resource sharing。假設我們想使用ajax從a.com的頁面上向b.com的頁面上要點資料,通常情況由於同源策略,這種請求是不允許的,瀏覽器也會返回 源不匹配 的錯誤,所以就有了 跨域 這個說法。...

cors方案解決跨域

瀏覽器的安全策略 同源策略。同源策略 協議名 網域名稱 埠號三者必須完全一致,才符合同源策略。只要有乙個不一樣,就違背同源策略,產生跨域。導致ajax請求失敗 cors 官方的解決方案 特點 可以發任意請求,相容性稍差。前端發請求拿資料 btn 按鈕 button script btn click ...