跨域請求產生錯誤的原因及處理方法

2020-12-23 51CTO

如果你在開發網站時曾經嘗試通過框架或是瀏覽器的 fetch、XHR 請求過外部 API 的話,那麼一定遇到過跨域請求,還有那個觸目驚心的 CORS 錯誤信息;今天咱們來討論跨域問題的原因以及解決方法。

跨域請求

如果你沒有沒有遇過,可以試著在瀏覽器的 console 頁輸入下面的代碼:

  1. const xhr = new XMLHttpRequest() 
  2. xhr.onreadystatechange = () => { 
  3.   if (xhr.readyState === 4) { 
  4.     console.log(xhr.status === 200 ? xhr.responseText : 'error') 
  5.   } 
  6. xhr.open('GET', 'https://google.com') 
  7. xhr.send() 

這段代碼通過調用瀏覽器的 XMLHttpRequest 對 Google 發出請求,而得到的結果如圖所示:

這就是跨域請求問題,當通過 JavaScript 對不同的來源發送請求時,這個請求的響應就會被瀏覽器攔截,不交給 JavaScript 處理。這裡的「不同來源」指的是目標資源與當前網頁的域(domain)、通訊協議(protocol)或網絡埠(port)只要有任一項不同,就算是不同來源。例如下面這幾個例子:

  1. 假設當前用戶在:https://example.com : 
  2. [✅] https://example.com/test -> 同域 
  3. [❌] https://m.example.com -> 不同域 
  4. [❌] https://example.com:3000 -> 埠不同 
  5. [❌] http://example.com -> 通訊協議不同 

理解什麼是跨域了,那為什麼瀏覽器要把跨域請求資源攔截掉呢?

其實這是考慮到用戶的信息安全。

假設小黑是一個惡意開發者,他編寫的網站會嘗試通過 XHR 打向百度、微博等目標網站;如果使用者原先就有目標網站的登錄狀態,小黑便能窺探他的隱私,得到不該取得的數據。再想想看,如果目標網站換成 Email、銀行、電商,如果沒有瀏覽器限制跨域請求的保護,惡意開發者便能為所欲為。

注意:跨域請求雖然會被瀏覽器攔截下來,但攔截的是響應(Response)而不是請求(Request)。

解決方案

關於跨域請求的解決方案有很多,例如 JSONP,也就是通過 HTML 中沒有跨域限制的標籤如 img、script 等,再通過指定回調函數,將響應的內容介接回 JavaScript 中;或是通過 iframe,繞過跨域保護獲取目標資源等。下面僅說明兩種常見也相對正規的解決方式。

1. CORS

最標準、正確的解決方法是通過 W3C 規範 的「 跨域資源共享(Cross-Origin Resource Sharing ,CORS)」,通過伺服器在 HTTP 頭中的設置,可以使瀏覽器能夠獲取不同來源的資源。

CORS 規範中,清楚定義了跨域存取控制的運作方式。

首先伺服器端需要在響應頭中加上如 Access-Control-Allow-Origin、Access-Control-Request-Method、Access-Control-Request-Headers 等設定,來限制伺服器所能接受的來源、請求的方法、可攜帶的頭等等。

當瀏覽器發送資源請求時,如果是簡單請求便會直接送出請求;若不符合前述條件,則會通過預檢(Preflighted)請求先敲敲門,確認是否可以通過伺服器的限制,然後才會發送正式的請求。

CORS 除了上述內容外,也有關於 Cookies 的傳送方式,如何允許跨域寫入 Cookies 等內容。

2. 代理伺服器

由於 CORS 的頭設置是在伺服器端,如果伺服器是自己的,那麼可以輕易的調整伺服器設置,讓前端能取得必要的資源;但如果你請求的是外部 API,總不能每次遇到 CORS 錯誤,就要求別人去修改頭設置吧。

簡單暴力的方法就是通過代理伺服器幫我們獲取資源;由於跨域保護的限制是瀏覽器的規範,只要不通過瀏覽器發送請求,自然也就不會有限制。

常見的作法是通過 nginx 做簡單的反向代理;例如在自己的開發環境,前後端分離的架構,前後端服務分別啟動在 3000 和 5000 埠,則可以用這樣的配置:

  1. server{ 
  2.   listen 3000; 
  3.   server_name localhost; 
  4.   location ^~ /api { 
  5.   proxy_pass http://localhost:5000; 
  6.   } 

當前端需要發送 API 請求時,可以直接請求 localhost:3000/api/...,這個請求會被 nginx 攔截,並轉發給後端所在的 localhost:5000,這樣就能簡單的繞過跨域保護了。

總結

跨域是前端常見的需求,CORS 的錯誤信息也是我們很容易被卡住的地方;其實只要清楚 CORS 規範中的 HTTP 頭設置,並在伺服器端做對應的調整,就可以順利的完成跨域請求。

【責任編輯:

趙寧寧

TEL:(010)68476606】

點讚 0

相關焦點

  • POST請求 報 HTTP status 415 錯誤(postman測試)
    測試時出現了HTTP status 415 錯誤。感覺很疑惑,有點懵,在網上找了些資料,總算知道為什麼出現這個問題了,記錄下來,防止自己以後再出現這個問題,也正好分享給各位同學,希望都同學們有所幫助。一、使用的工具:測試工具:postman二、出現的問題:使用postman測試使出現了HTTP status 415 的報錯。
  • 聽說 AJAX 請求不安全?什麼鬼?
    從入坑前端開始,一直到現在,AJAX請求都是以極高的頻率重複出現,也解決過不少AJAX中遇到的問題,如跨域調試,錯誤調試等等。從這種,發現了一個共通現象:那就是每次和後臺人員對接時,他們都會提到AJAX請求不安全,請用普通http請求!
  • 寬帶連接錯誤的處理辦法651、691、678、645、815...
    寬帶連接錯誤691(由於域上的用戶名或密碼無效而拒絕訪問)/錯誤635(未知錯誤)的處理流程如下:(1)用戶名密碼填寫錯誤(2)如果用戶帳號密碼填寫無誤,則進入下一步繼續處理;建議重建撥號軟體(如果不懂裝撥號軟體,可參考戶重新):-如果重裝撥號軟體後正常,原因為「撥號軟體丟失
  • 鋼琴出現雜音的常規原因及處理方法
    下面簡單介紹幾種常見的原因及處理方法:1同音弦組上的兩根或三根琴弦,如果弦軸孔過於靠近,振動時弦與弦相蹭,會發出噝噝聲。  處理方法:用螺絲刀把相蹭的兩根弦劈開,然後把音調準。對難以劈開的琴弦可用螺絲刀從弦枕以上劈開,並把兩根或三根弦之間絆呢條使弦與弦之間分開。
  • 跨域審判「+」 群眾讚譽有加
    11月17日《人民法院報》第8版以《跨域審判「+」群眾讚譽有加》為題刊發介紹了我院貫徹落實上級法院部署運用跨域審判「+」模式通過跨域立案、跨域調解、跨域法律諮詢等訴訟服務,實現了跨域審判「+」模式轄區全覆蓋從根本上減輕當事人訴累
  • 用JavaScript發出HTTP請求的不同方法
    以下代碼展示了使用不同替代方法的基本HTTP GET和POST示例。現在開始吧~XMLHttpRequestXMLHttpRequest對象可用於從Web伺服器請求數據。它是這次比較中最早的方法,儘管其他選擇都優於它,但由於其向後兼容性和成熟度,它仍然有效且有用。
  • 出現網頁錯誤時, 404、502這些數字代表啥
    得到伺服器的IP位址後,我們電腦上的瀏覽器要向伺服器發出想加載網頁資源的請求,建立一個瀏覽器與伺服器的連接。 接著,瀏覽器會發送網頁連結請求,伺服器收到請求後,進行相應的處理,比如說身份驗證等。這一步的目的是,查看你有沒有訪問伺服器內相應資源的權限。
  • 津、滬兩地海事法院攜手 全國首例海事訴訟跨域立案
    :李玉素   中新網天津8月13日電 (記者 張道正 通訊員 吳玉萍 楊在蔚 黃丹)為加快推進跨域立案訴訟服務改革,推動訴訟服務事項跨區域辦理,跨層級聯動辦理,解決好異地訴訟難等問題,8月13日,中國首例海事訴訟跨域立案在天津海事法院和上海海事法院之間完成
  • 牆面發黴是什麼原因?牆壁發黴處理方法!
    很多人的家庭的牆壁經常會出現掉皮發黴的現象,這是什麼原因呢?牆面發黴的原因有很多種,黴菌不僅影響居室美觀,牆壁發黴對人體健康會造成很大的危害,牆體黴菌孢子在適合的環境下很容易滋生與漫延。那麼牆面發黴是什麼原因?有什麼處理方法嗎?下面小編就給大家介紹一下處理。
  • 【電聲硬體】吉他產生回授嘯叫的常見原因以及對應方法
    簡而言之「嘯叫」產生的原因就是因為一個循環與疊加。音箱發出的聲音又再次進入話筒,被話筒拾取後又再次進入音箱放大,出來後再次被話筒拾取……這樣在短時間內形成一個越來越大的循環,並且產生不斷增強的電聲信號,也就發出了「嘯叫」。對於採用麥克風類拾音器的木吉他來說,「嘯叫」也會更容易產生。
  • 網站打不開常見錯誤以及解決方法
    下面鴻鑫瑞就來分析分析我們遇到的問題就是什麼原因導致的。一、通過瀏覽器返回的錯誤狀態碼查找問題 400 - 錯誤的請求。401 - 訪問被拒絕。IIS 定義了許多不同的 401 錯誤,它們指明更為具體的錯誤原因。這些具體的錯誤代碼在瀏覽器中顯示,但不在 IIS 日誌中顯示:401.1 - 登錄失敗。401.2 - 伺服器配置導致登錄失敗。
  • 流鼻血真不是上火,2大原因別不當回事!警惕錯誤處理方法
    鼻出血的原因大致可分為兩種:第一種:鼻部疾病。比較常見的有鼻炎、鼻竇炎、急性鼻炎、乾燥性鼻炎、萎縮性鼻炎,急性上頜竇炎等,或者鼻子受外傷、鼻黏膜乾燥等等,都會引起流鼻血。流鼻血的錯誤止血方法,要警惕1、仰頭止血錯誤的原因:如果流鼻血這樣做,會使鼻腔裡面的血液倒流進鼻咽部或者口腔裡,甚至胃裡,會引起噁心嘔吐。
  • 狗狗有皮屑的原因及處理方法
    有皮屑本來是一件很正常的事,因為這是由於身體新陳代謝所引起的
  • 出現網頁錯誤時 ,數字502、404等分別是什麼意思?
    得到伺服器的IP位址後,我們電腦上的瀏覽器要向伺服器請求我們想要加載的網頁資源,建立一個瀏覽器與伺服器的連接。 接著,瀏覽器會發送網頁連結請求,伺服器收到請求後,進行相應的處理,比如說身份的驗證等。這一步的目的是,查看你有沒有訪問伺服器內相應資源的權限。
  • 虎皮蘭葉片捲曲的原因和處理方法!
    虎皮蘭葉片捲曲發生的原因有很多種,爛根以後根系無法吸收水分,長期沒澆水根尖枯萎,土壤板結澆水水分進不到土壤中心,肥效過足燒根導致根系無法吸收水分,這些都是葉片捲曲的主要原因,歸結起來就是葉片缺水了。處理方法:首先澆一遍透水,看到花盆底部有水分流出就停止。等盆面的水滲透下去,用小花鏟鏟一下淺表土,大約深度3公分,若是還處於乾燥狀態,就要及時更換新土。新土可以使用(田園土+腐殖土+淡水河沙)各取1/3混合。
  • 級進模中衝壓件產生翻料及扭曲的原因及抑制方法
    衝壓時產生翻料、扭曲的原因 在級進模中,通過衝切衝壓件周邊餘料的方法,來形成衝件的外形。衝件產生翻料、扭曲的主要原因為衝裁力的影響。衝裁時,由於衝裁間隙的存在,材料在凹模的一側受拉伸(材料向上翹曲), * 凸模側受壓縮。當用卸料板時,利用卸料板壓緊材料,防止凹模側的材料向上翹曲,此時,材料的受力狀況發生相應的改變。
  • 舒曼鋼琴帶你認識鋼琴雜音產生的原因和消除方法
    「舒曼鋼琴」字樣,免費訂閱 鋼琴在彈奏時,在流暢悅耳的琴聲中,有時會混雜著咯吱咯吱、沙沙和類似木頭碰擦聲等各種雜音,嚴重破壞了鋼琴的音質,下面就鋼琴雜音產生的原因和處理方法作一介紹。 外部造成的原因是由於硬的物品放在琴蓋上,或者有東西碰擦在鋼琴旁,再或者是地板太軟,經不起這麼沉重的鋼琴而彎曲變形,特別是老式房屋的地板,當鋼琴彈奏時,這些物件與鋼琴某一音律一致時,由於 共振的作用產生了上述雜音,但有一點應注意,有時周圍家具上放置的物品也會產生共振,但檢查者憑聽覺是很容易鑑別的。
  • 常識:胎位枕後位的原因及處理方法
    發生枕後位的主要原因有:  1.骨盆異常 男型骨盆及猿型骨盆,入口平面前半部分狹窄,後半部分較寬大,胎頭枕部易取枕後位銜接,而這兩種骨盆中骨盆平面和出口平面狹窄,骨盆呈漏鬥型,使枕後位銜接的胎頭難以轉向前方,容易發展成為持續性枕後位。而均小骨盆由於骨盆各徑線均小,骨盆狹窄,影響胎頭旋轉,同樣易引起持續性枕後位。
  • 「跨域審判+」 功能延伸遍開花
    新冠肺炎疫情發生後,為充分發揮審判職能,切實保障人民群眾健康安全,呼和浩特鐵路運輸兩級法院充分利用「跨域審判+」模式開展工作,在全面推行跨域調解、跨域庭審的基礎上,將該模式「+」的功能進一步拓展,不斷創新工作舉措,延伸至跨域會議、跨域講座等領域,確保疫情防控和審判執行兩不誤。