1、跨域請求
從本域名訪問不同域名或端口的http請求統(tǒng)一稱為跨域請求,為了安全起見,瀏覽器會阻止從腳本中(比如js、css)發(fā)起http跨域請求,但資源以嵌入的方式是可以加載的。
以下是可能嵌入跨源的資源的一些示例:
- <script src="..."></script>標(biāo)簽嵌入跨域腳本。語法錯誤信息只能在同源腳本中捕捉到。
- <link rel="stylesheet" href="...">標(biāo)簽嵌入CSS。由于CSS的松散的語法規(guī)則,CSS的跨域需要一個設(shè)置正確的Content-Type消息頭。不同瀏覽器有不同的限制:
IE, Firefox, Chrome, Safari (跳至CVE-2010-0051)部分 和 Opera。- <img>嵌入圖片。支持的圖片格式包括PNG,JPEG,GIF,BMP,SVG,...
- <video> 和 <audio>嵌入多媒體資源
- <object>,<embed>和<applet>的插件
- @font-face
引入的字體。一些瀏覽器允許跨域字體( cross-origin fonts),一些需要同源字體(same-origin fonts)。- <frame>
和 <iframe>載入的任何資源。站點可以使用
X-Frame-Options消息頭來阻止這種形式的跨域交互。
非嵌入式http跨域請求分兩種:
- 簡單請求
簡單請求需要滿足三個條件:- 請求的methods僅限于GET、HEAD、POST
- Content-Type頭值必須為text/plain|multipart/form-data|application/x-www-form-urlencoded其中之一
- 請求頭部不可以添加額外的頭部
此類請求只是簡單的發(fā)送請求,是否能成功,需要服務(wù)器端配置Access-Control-Allow-Origin: yourDomain | *
- 預(yù)檢請求
與前述簡單請求不同,“需預(yù)檢的請求”要求必須首先使用 OPTIONS
方法發(fā)起一個預(yù)檢請求到服務(wù)器,以獲知服務(wù)器是否允許該實際請求。"預(yù)檢請求“的使用,可以避免跨域請求對服務(wù)器的用戶數(shù)據(jù)產(chǎn)生未預(yù)期的影響
簡單請求需要滿足三個條件:- 請求的methods為PUT 、DELETE 、CONNECT 、OPTIONS 、TRACE 、PATCH中任一種HTTP方法
- Content-Type頭值不為text/plain|multipart/form-data|application/x-www-form-urlencoded其中之一
- 請求頭部添加了額外的頭部
所謂預(yù)檢請求,就是在正式請求發(fā)送之前,先發(fā)送一個OPTIONS請求去服務(wù)器詢問服務(wù)器是否處理正式請求的method以及帶的headers,如果處理,那就發(fā)送正式請求,否則報錯 code 405。
比如發(fā)送一個跨域的get請求,但是添加了一個headers: {myheader: true}, 這樣滿足了預(yù)檢請求的條件,瀏覽器攔截到該get請求后,檢查到headers中有額外headers,那么就會自己先發(fā)一個OPTIONS請求,帶上get請求的method與headers去訪問服務(wù)器。
2、跨域請求需要帶上cookie
當(dāng)發(fā)送跨域請求時,有時需要帶上cookie或者其他證書去認(rèn)證,需要在前端請求headers中添加withCredentials:true,這樣才會帶上cookie,并且服務(wù)器端的響應(yīng)中需攜帶 Access-Control-Allow-Credentials: true,否則瀏覽器將不會把響應(yīng)內(nèi)容返回給請求的發(fā)送者。
注意,對于附帶身份憑證的請求,服務(wù)器不得設(shè)置 Access-Control-Allow-Origin 的值為“*”。
這是因為請求的首部中攜帶了 Cookie 信息,如果 Access-Control-Allow-Origin 的值為“*”,請求將會失敗。而將 Access-Control-Allow-Origin 的值設(shè)置為http://yourhost.com,則請求將成功執(zhí)行。
另外,響應(yīng)首部中也攜帶了 Set-Cookie 字段,嘗試對 Cookie 進行修改。如果操作失敗,將會拋出異常。
參考:
1、瀏覽器的同源策略
2、HTTP訪問控制(CORS)
3、前后端通訊系統(tǒng)
4、web font 字體跨域