CORS——跨域請求那些事兒

 

【本期嘉賓介紹】睿得,具有多年研發、運維、安全等IT相關從業經歷。目前從事CDN、存儲、視頻直播點播的技術支持。喜愛鉆研,喜愛編碼,喜愛分享。


699a892b2bcb6e4fe72e215c530339d87f32c2af
在日常的項目開發時會不可避免的需要進行跨域操作,而在實際進行跨域請求時,經常會遇到類似 No 'Access-Control-Allow-Origin' header is present on the requested resource.這樣的報錯。

這樣的錯誤,一般是由于CORS跨域驗證機制設置不正確導致的,本文將詳細講解CORS跨域驗證機制的原理,讓您輕松掌握CORS跨域設置的使用方法,安全、方便的進行前端開發。

什么是CORS

CORS(Cross-Origin Resource Sharing 跨源資源共享),當一個請求url的協議、域名、端口三者之間任意一與當前頁面地址不同即為跨域。

例如最常見的,在一個域名下的網頁中,調用另一個域名中的資源。

相對于上面這種靜態的調用方式,還可以通過Ajax技術來動態發起跨域請求。例如如下的方式,利用XMLHttpRequest對象發送一個GET請求,獲取另一個域名下的圖片內容。

<!DOCTYPE html> 
<html><head>CORS Test</head><body><div id="img_Div"></div><script type="text/javascript">  //XmlHttpRequest對象  function createXmlHttpRequest(){  if(window.ActiveXObject){ //如果是IE瀏覽器  return new ActiveXObject("Microsoft.XMLHTTP");  }else if(window.XMLHttpRequest){ //非IE瀏覽器  return new XMLHttpRequest();  }  }  function getFile() {var img_Container = document.getElementById("img_Div");var xhr = createXmlHttpRequest();xhr.open('GET', 'http://oss.youkouyang.com/1.jpg', true);xhr.setRequestHeader('Content-Type', 'image/jpeg');xhr.responseType = "blob";xhr.onload = function() {if (this.status == 200) {var blob = this.response;var img = document.createElement("img");img.onload = function(e) {window.URL.revokeObjectURL(img.src); };img.src = window.URL.createObjectURL(blob);img_Container.appendChild(img);    }}xhr.send(null);}</script><div class="row"><input type="button" onclick="getFile()" value="Get" /></div></body>
</html>??

CORS的作用

為了改善網絡應用程序,開發人員要求瀏覽器供應商允許跨域請求。跨域請求主要用于:

  • 調用XMLHttpRequest或fetchAPI通過跨站點方式訪問資源
  • 網絡字體,例如Bootstrap(通過CSS使用@font-face 跨域調用字體)
  • 通過canvas標簽,繪制圖表和視頻。

CORS的安全隱患

跨域請求和Ajax技術都會極大地提高頁面的體驗,但同時也會帶來安全的隱患,其中最主要的隱患來自于CSRF(Cross-site request forgery)跨站請求偽造。

CSRF攻擊的大致原理是:

  1. 用戶通過瀏覽器,訪問正常網站A(例如某銀行),通過用戶的身份認證(比如用戶名/密碼)成功A網站。
  2. 網站A產生Cookie信息并返回給用戶的瀏覽器;?
  3. 用戶保持A網站頁面登錄狀態,在同一瀏覽器中,打開一個新的TAB頁訪問惡意網站B;
  4. 網站B接收到用戶請求后,返回一些攻擊性代碼,請求A網站的資源(例如轉賬請求);
  5. 瀏覽器執行惡意代碼,在用戶不知情的情況下攜帶Cookie信息,向網站A發出請求。
  6. 網站A根據用戶的Cookie信息核實用戶身份(此時用戶在A網站是已登錄狀態),A網站會處理該請求,導致來自網站B的惡意請求被執行。

CORS驗證機制

出于安全原因,瀏覽器限制從腳本中發起的跨域HTTP請求。默認的安全限制為同源策略, 即JavaScript或Cookie只能訪問同域下的內容。
W3C推薦了一種跨域的訪問驗證的機制,即CORS(Cross-Origin Resource Sharing 跨源資源共享)。
這種機制讓Web應用服務器能支持跨站訪問控制,使跨站數據傳輸更加安全,減輕跨域HTTP請求的風險。
CORS驗證機制需要客戶端和服務端協同處理。

CORS瀏覽器支持情況

目前主流瀏覽器都已基本提供對跨域資源共享的支持,移動端瀏覽器也幾乎全部支持。


客戶端處理機制

基于上述的CSRF的風險,各主流的瀏覽器都會對動態的跨域請求進行特殊的驗證處理。驗證處理分為簡單請求驗證處理和預先請求驗證處理。

簡單請求

當請求同時滿足下面兩個條件時,瀏覽器會直接發送GET請求,在同一個請求中做跨域權限的驗證。

請求方法是下列之一:

  • GET
  • HEAD
  • POST

請求頭中的Content-Type請求頭的值是下列之一:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

簡單請求時,瀏覽器會直接發送跨域請求,并在請求頭中攜帶Origin 的header,表明這是一個跨域的請求。
服務器端接到請求后,會根據自己的跨域規則,通過Access-Control-Allow-Origin和Access-Control-Allow-Methods響應頭,來返回驗證結果。
如果驗證成功,則會直接返回訪問的資源內容。


如果驗證失敗,則返回403的狀態碼,不會返回跨域請求的資源內容。


可以通過瀏覽器的Console查看具體的驗證失敗原因

預先請求

當請求滿足下面任意一個條件時,瀏覽器會先發送一個OPTION請求,用來與目標域名服務器協商決定是否可以發送實際的跨域請求。

請求方法不是下列之一:

  • GET
  • HEAD
  • POST

請求頭中的Content-Type請求頭的值不是下列之一:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

?

瀏覽器在發現頁面中有上述條件的動態跨域請求的時候,并不會立即執行對應的請求代碼,而是會先發送Preflighted requests(預先驗證請求),Preflighted requests是一個OPTION請求,用于詢問要被跨域訪問的服務器,是否允許當前域名下的頁面發送跨域的請求。?

?

OPTIONS請求頭部中會包含以下頭部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers。
服務器收到OPTIONS請求后,設置Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers頭部與瀏覽器溝通來判斷是否允許這個請求。
如果Preflighted requests驗證通過,瀏覽器才會發送真正的跨域請求。
  

如果Preflighted requests驗證失敗,則會返回403狀態,瀏覽器不會發送真正的跨域請求。
?

?可以通過瀏覽器的Console查看具體的驗證失敗原因

?

帶認證的請求

默認情況下,跨源請求不提供憑據(cookie、HTTP認證及客戶端SSL證明等)。通過將withCredentials屬性設置為true,可以指定某個請求應該發送憑據。
xhr.withCredentials = true;
如果服務器接收帶憑據的請求,會用下面的HTTP頭部來響應。
Access-Control-Allow-Credentials: true
服務器還可以在Preflight響應中發送這個HTTP頭部,表示允許源發送帶憑據的請求。


如果發送的是帶憑據的請求,但服務器的響應中沒有包含這個頭,那么瀏覽器就不會把響應交給JavaScript(responseText中將是空字符串,size為0)。

注意,當withCredentials屬性設置為true,需要response header中的'Access-Control-Allow-Origin'為一個確定的域名,而不能使用'*'這樣的通配符。

服務端處理機制

服務器端對于跨域請求的處理流程如下:

  1. 首先查看http頭部有無origin字段;
  2. 如果沒有,或者不允許,直接當成普通請求處理,結束;
  3. 如果有并且是允許的,那么再看是否是preflight(method=OPTIONS);
  4. 如果不是preflight(簡單請求),就返回Allow-Origin、Allow-Credentials等,并返回正常內容。
  5. 如果是preflight(預先請求),就返回Allow-Headers、Allow-Methods等,內容為空;

HTTP Header

Request header

Origin

Origin頭在跨域請求或預先請求中,標明發起跨域請求的源域名。

Access-Control-Request-Method

Access-Control-Request-Method頭用于表明跨域請求使用的實際HTTP方法

Access-Control-Request-Headers

Access-Control-Request-Headers用于在預先請求時,告知服務器要發起的跨域請求中會攜帶的請求頭信息

Response header

Access-Control-Allow-Origin

Access-Control-Allow-Origin頭中攜帶了服務器端驗證后的允許的跨域請求域名,可以是一個具體的域名或是一個*(表示任意域名)。簡單請求時,瀏覽器會根據此響應頭的內容決定是否給腳本返回相應內容,預先驗證請求時,瀏覽器會根據此響應頭決定是否發送實際的跨域請求。

Access-Control-Expose-Headers

Access-Control-Expose-Headers頭用于允許返回給跨域請求的響應頭列表,在列表中的響應頭的內容,才可以被瀏覽器訪問。

Access-Control-Max-Age

Access-Control-Max-Age用于告知瀏覽器可以將預先檢查請求返回結果緩存的時間,在緩存有效期內,瀏覽器會使用緩存的預先檢查結果判斷是否發送跨域請求。

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials用于告知瀏覽器當withCredentials屬性設置為true時,是否可以顯示跨域請求返回的內容。簡單請求時,瀏覽器會根據此響應頭決定是否顯示響應的內容。預先驗證請求時,瀏覽器會根據此響應頭決定在發送實際跨域請求時,是否攜帶認證信息。

Access-Control-Allow-Methods

Access-Control-Allow-Methods用于告知瀏覽器可以在實際發送跨域請求時,可以支持的請求方法,可以是一個具體的方法列表或是一個*(表示任意方法)。簡單請求時,瀏覽器會根據此響應頭的內容決定是否給腳本返回相應內容,預先驗證請求時,瀏覽器會根據此響應頭決定是否發送實際的跨域請求。

Access-Control-Allow-Headers

Access-Control-Allow-Headers用于告知瀏覽器可以在實際發送跨域請求時,可以支持的請求頭,可以是一個具體的請求頭列表或是一個*(表示任意請求頭)。簡單請求時,瀏覽器會根據此響應頭的內容決定是否給腳本返回相應內容,預先驗證請求時,瀏覽器會根據此響應頭決定是否發送實際的跨域請求。?

配置CORS規則

nginx上的CORS配置

OSS上的CORS配置?

CDN上的CORS配置

注意:由于CDN的緩存特性,CDN配合OSS時,需要在CDN中設置CORS配置。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282896.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282896.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282896.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

oracle 數據執行計劃,Oracle里常見的執行計劃

本文介紹了Oracle數據庫里常見的執行計劃&#xff0c;使用的Oracle數據庫版本為11.2.0.1。1、與表訪問相關的執行計劃Oracle數據庫里與表訪問有關的兩種方法&#xff1a;全表掃描和ROWID掃描。反映在執行計劃上&#xff0c;與全表掃描對應的執行計劃中的關鍵字是“TABLE ACCESS…

.NET MAUI實戰 Dispatcher

詳細內容這一期分享的內容非常簡單&#xff0c;在之前使用過WPF的開發者對MVVM開發模式下ViewModel中后臺線程轉UI線程并不陌生使用Appplication.Current.Dispatcher。那么在.NET MAUI中也有同樣的機制&#xff0c;存在于.NET MAUI Shell對象中。那么什么是Shell&#xff1f;官…

GDB 配置

GDB 配置 使用 GDB 擴展來配置 GDB 事實上我還是覺得原生的 GDB 就挺好&#xff0c;速度快&#xff0c;需要查看什么執行命令就可以。 GDB DashBoard https://github.com/cyrus-and/gdb-dashboard $sudo mkdir -m 777 ~/gdbinit; cd ~/gdbinit $git clone https://github.com/c…

Oracle區分中文和英文,oracle中中英文段落劃分實現

oracle中關于中文占用字節數&#xff0c;不同的數據庫有不同的情況&#xff0c;有的占用兩個字節、有的占用三個字節&#xff0c;現在測試環境的數據庫中文占用三個字節&#xff0c;要實現由中英文組成的段落字符串&#xff0c;按照每行占用多少字節重新分段&#xff0c;具體應…

未來哪些行業值得加入?

閱讀本文大概需要5分鐘。這個問題很多讀者都問過&#xff0c;基本上每隔幾篇原創就會有人留言問&#xff0c;還有公眾號后臺和知乎私聊。之前在一次留言中我承諾專門開一篇文章來聊聊這個話題&#xff0c;今天想著要兌現這個諾言了。為啥最近會存在這個問題呢&#xff0c;原因其…

虛擬機網絡配置詳解(NAT、橋接、Hostonly)

VirtualBox中有四種網絡連接方式: NATBridged AdapterInternalHost-only AdapterVMWare中有三種&#xff0c;其實它跟VMWare的網絡連接方式都是一樣的概念&#xff0c;只是比VMWare多了Internal方式 在介紹四種工作模式之前&#xff0c;先說下虛擬網卡&#xff0c;虛擬機安裝好…

Oracle收款核銷了怎么撤銷,21應收收款-核銷取消或核銷調整

注&#xff1a;本課程不包含學習下載資料目標人群&#xff1a;1、Oracle ERP/EBS初級顧問和技術顧問&#xff1b; 1、Oracle ERP/EBS用戶熟練學習ERP系統的基本設置功能&#xff1b; 2、Oracle ERP/EBS財務初級顧問的學習&#xff1b; 3、其他對Oracle ERP/EBS有興趣的想轉行如…

微軟宣布正式開源 Azure IoT Edge 邊緣計算服務

開發四年只會寫業務代碼&#xff0c;分布式高并發都不會還做程序員&#xff1f; 微軟宣布&#xff0c;去年年底公開預覽的 Azure IoT Edge 邊緣計算服務已進入官方版&#xff0c;并通過 GitHub 將其開源。Azure IoT Edge 主要將基于云的分析和定制的業務邏輯轉移到邊緣設備&a…

Windows下安裝BeautifulSoup

電腦首先要安裝好了python&#xff0c;我安裝的是2.7。 下面就是bs4的安裝過程了: 1.去官網下載BeautifulSoup4 2017.02.10目前最新版本&#xff1a;Beautiful Soup 4.3.2 2.解壓文件 將下載得到的壓縮包解壓到任意文件夾&#xff0c;路徑不含中文 3.打開cmd命令提示符 winr&am…

BZOJ1578: [Usaco2009 Feb]Stock Market 股票市場

S<50只股票D<10天的價格給出&#xff0c;求第一天開始用n<200000元最后能得到的最大錢數&#xff0c;保證答案<500000。 做D次完全背包即可&#xff0c;每次做完把dp數組清空。 1 #include<cstdio>2 #include<cstring>3 #include<algorithm>4 #i…

OC如何跳到系統設置里的各種設置界面

當 iOS系統版本 < iOS7時 , 只能跳轉到 系統設置頁面 &#xff0c;樓主試了下&#xff0c;非真機是沒有任何效果的 當iOS系統版本 < iOS 10.0 時 NSURL *url [NSURL URLWithString:"prefs:rootLOCATION_SERVICES"]; if( [[UIApplication sharedApplication]can…

oracle 注冊程序,oracle 靜態注冊

1. 最近在裝ASMDATAGUARD&#xff0c; 在靜態注冊上面吃了大虧&#xff0c;現總結如下2. 在Asm環境中&#xff0c;listener監聽器在grid用戶下DGLSN (DESCRIPTION_LIST (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST asm)(PORT 1521))))SID_LIST_DGLSN (SID_LIST (SID_DESC (…

Linux下find用法總結

find:實時查找工具&#xff0c;通過遍歷指定起始路徑下的文件系統層級結構完成文件查找:工作特性:查找速度略慢精確查找實時查找用法:find [option] [查找起始路徑][查找條件][處理動作]查找起始路徑&#xff1a;指定具體搜索目標起始路徑&#xff1b;默認為當前目錄查找條件:指…

虛擬DOM Diff算法解析

React中最神奇的部分莫過于虛擬DOM&#xff0c;以及其高效的Diff算法。這讓我們可以無需擔心性能問題而”毫無顧忌”的隨時“刷新”整個頁面&#xff0c;由虛擬DOM來確保只對界面上真正變化的部分進行實際的DOM操作。React在這一部分已經做到足夠透明&#xff0c;在實際開發中我…

生成ID模板:年月日時分秒+6位自增碼

因為生成訂單ID、商品ID 或者什么什么ID的&#xff0c;不想用自增&#xff0c;又怕反復&#xff0c;于是就用 年與日時分秒 6位自增碼 &#xff08;共計20位長度&#xff09;來當作ID 注意&#xff1a;假設你的ID是Long型。就要注意&#xff0c;Long的最大長度為19位&#xf…

oracle optimizer_features_enable,Oracle Optimizer:遷移到使用基于成本的優化器—–系列2.1-數據庫專欄,ORACLE...

oracle optimizer:遷移到使用基于成本的優化器—–系列2.1系列之二包含影響優化器選擇執行計劃的初始化參數和oracle內部隱藏參數&#xff0c;合理設置這些參數對于優化器是相當重要的。6.影響優化器的初始化參數除了生成統計資料之外&#xff0c;下面提及的參數設置在你的系統…

Azure 跨訂閱遷移資源踩坑記

突然收到微軟的郵件&#xff0c;提示我的一個 Azure 訂閱已經到期&#xff0c;所以轉為“禁用”狀態&#xff0c;只能進行數據的導出和處理。在這個訂閱里有不少較重要的資源在跑&#xff0c;直接關了可不行…于是開啟了一個支持事件&#xff0c;臺灣美眉的態度和聲線真的沒話說…

階乘的精確性

/* 輸入不超過1000的正整數n&#xff0c;輸出n!1*2*3*……*n的精確結果。 樣例輸入&#xff1a;30 樣例輸出&#xff1a;265252859812191058636308480000000 例如 n3&#xff1b;s6&#xff1b; n4&#xff1b;s24&#xff1b; n5&#xff1b;s120&#xff1b; 1000的階乘需要一…

Optaplanner規劃引擎的工作原理及簡單示例(1)

在之前的文章中&#xff0c;老猿已介紹過APS及規劃的相關內容&#xff0c;也對Optaplanner相關的概念和一些使用示例進行過介紹&#xff0c;接下來的文章中&#xff0c;我會自己做一個規劃小程序 - 一個關于把任務分配到不同的機臺上進行作來的小程序&#xff0c;并在這個小程序…

[HNOI2017]禮物

題目描述 我的室友最近喜歡上了一個可愛的小女生。馬上就要到她的生日了&#xff0c;他決定買一對情侶手環&#xff0c;一個留給自己&#xff0c;一個送給她。每個手環上各有 n 個裝飾物&#xff0c;并且每個裝飾物都有一定的亮度。 但是在她生日的前一天&#xff0c;我的室友突…