摘要:設(shè)置的值,為其當前域或其當前域的父域。場景文檔中的一個腳本執(zhí)行以下語句即可通過同源檢測跨源網(wǎng)絡(luò)訪問同源策略控制了不同源之間的交互。服務(wù)器確認允許之后,才發(fā)起實際的請求。
文章大綱
同源策略
同源是什么?
如何跨源,以及場景應(yīng)用
源的更改
跨源網(wǎng)絡(luò)訪問
跨源腳本API訪問
跨源數(shù)據(jù)存儲訪問
了解CORS
CORS是什么?
CORS功能概述
CORS關(guān)于Cookie
CORS的簡單請求
CORS預(yù)檢請求又是什么?
其他
參考
同源策略 同源是什么?在web瀏覽器中,同源策略 限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用于隔離潛在惡意文件的重要安全機制。
如果兩個頁面的
1.協(xié)議
2.端口(如果有指定)
3.域名
三者都相同,則兩個頁面具有相同的源。
舉例說明 http://store.example.com/dir/page.html 同源檢測的示例:
URL | 結(jié)果 | 原因 |
---|---|---|
http://store.example.com/index.html | 成功 | |
http://store.example.com/dir/another.html | 成功 | |
https://store.example.com/index.html | 失敗 | 不同協(xié)議 ( https和http ) |
http://store.example.com:81/index.html | 失敗 | 不同端口 ( 81和80) |
http://news.example.com/index.html | 失敗 | 不同域名 ( news和store ) |
http://example.com/index.html | 失敗 | 不同域名 (store是一個多帶帶的自域) |
以下為4種可以遇到的跨源
源的更改頁面可能會因某些限制而改變他的源。
設(shè)置 document.domain 的值,為其當前域或其當前域的父域。
場景 http://store.example.com/dir/page.html 文檔中的一個腳本執(zhí)行以下語句 document.domain = "company.com" 即可通過同源檢測跨源網(wǎng)絡(luò)訪問
同源策略控制了不同源之間的交互。
使用 CORS 允許跨源訪問。
場景 由瀏覽器發(fā)起的跨域 HTTP 請求 (這個大家接觸的最多)跨源腳本API訪問
Javascript的APIs中,允許文檔間直接相互引用。但是當兩個文檔的源不同時,一些引用方式將對 API對象的訪問添加限制
可以使用window.postMessage
場景 使用 嵌套的時候,父子頁面的通信跨源數(shù)據(jù)存儲訪問
存儲在瀏覽器中的數(shù)據(jù),如localStorage和IndexedDB,以源進行分割。每個源都擁有自己多帶帶的存儲空間,一個源中的Javascript腳本不能對屬于其它源的數(shù)據(jù)進行讀寫操作。
場景 null了解CORS CORS是什么?
MDN的網(wǎng)站給出了這樣的2種解釋:
CORS (Cross-Origin Resource Sharing,跨域資源共享)是一個系統(tǒng),它由一系列傳輸?shù)腍TTP頭組成,這些HTTP頭決定瀏覽器是否阻止前端 JavaScript 代碼獲取跨域請求的響應(yīng)。 CORS 給了web服務(wù)器這樣的權(quán)限,即服務(wù)器可以選擇,允許跨域請求訪問到它們的資源。跨域資源共享(CORS) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的Web應(yīng)用被準許訪問來自不同源服務(wù)器上的指定的資源。當一個資源從與該資源本身所在的服務(wù)器不同的域、協(xié)議或端口請求一個資源時,資源會發(fā)起一個跨域 HTTP 請求。
實際上著兩種解釋都一樣。我給出這樣的理解:CORS賦予服務(wù)端(通常所說的后端)一個能力,自己控制哪些瀏覽器的請求可以訪問到它的資源,來解決跨域問題。
附:所有的 CORS 頭
HTTP頭 | 功能 |
---|---|
Access-Control-Allow-Origin | 指示請求的資源能共享給哪些域。 |
Access-Control-Allow-Credentials | 指示當請求的憑證標記為 true 時,是否響應(yīng)該請求。 |
Access-Control-Allow-Headers | 用在對預(yù)請求的響應(yīng)中,指示實際的請求中可以使用哪些 HTTP 頭。 |
Access-Control-Allow-Methods | 指定對預(yù)請求的響應(yīng)中,哪些 HTTP 方法允許訪問請求的資源。 |
Access-Control-Expose-Headers | 指示哪些 HTTP 頭的名稱能在響應(yīng)中列出。 |
Access-Control-Max-Age | 指示預(yù)請求的結(jié)果能被緩存多久。 |
Access-Control-Request-Headers | 用于發(fā)起一個預(yù)請求,告知服務(wù)器正式請求會使用那些 HTTP 頭。 |
Access-Control-Request-Method | 用于發(fā)起一個預(yù)請求,告知服務(wù)器正式請求會使用哪一種 HTTP 請求方法。 |
Origin | 指示獲取資源的請求是從什么域發(fā)起的。 |
功能概述 TL;DR
規(guī)范要求,對那些可能對服務(wù)器數(shù)據(jù)產(chǎn)生副作用的 HTTP 請求方法(特別是 GET 以外的 HTTP 請求,或者搭配某些 MIME 類型的 POST 請求),瀏覽器必須首先使用 OPTIONS 方法發(fā)起一個預(yù)檢請求(preflight request),從而獲知服務(wù)端是否允許該跨域請求。服務(wù)器確認允許之后,才發(fā)起實際的 HTTP 請求。在預(yù)檢請求的返回中,服務(wù)器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認證相關(guān)數(shù)據(jù))。
一句話概述:非簡單請求時,會先發(fā)送預(yù)檢請求,允許后再發(fā)送實際請求
附:node-express框架下,服務(wù)端的跨域設(shè)置
app.all("*", function (req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Content-Type"); res.header("Access-Control-Allow-Methods", "*"); next(); });CORS關(guān)于Cookie
CORS請求默認不發(fā)送Cookie和HTTP認證信息,如果想要知道用cookie就要注意3點
Client端 new XMLHttpRequest() 中 withCredentials 設(shè)置為 true
Serive端 HTTP頭 Access-Control-Allow-Credentials 設(shè)置為 true
Serive端 HTTP頭 Access-Control-Allow-Origin 不能設(shè)為星號,必須指定明確的、與請求網(wǎng)頁一致的域名
所以上面的例子要想發(fā)送cookie
// service端 `res.header("Access-Control-Allow-Credentials", true);` `res.header("Access-Control-Allow-Origin", "具體的域名");` // client端 Jquery `ajax()` `xhrFields: {withCredentials: true}` Axios `axios.defaults.withCredentials = true`CORS的簡單請求
上面講了簡單請求,但那些才是簡單請求呢?我們稱:若不會觸發(fā) CORS 的預(yù)檢請求,稱這樣的請求為“簡單請求”
以下為簡單請求:
HTTP Method 組成只能是以下幾種
GET
POST
HEAD
HTTP Headers 組成
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 只包含以下類型 (form表單請求)
application/x-www-form-urlencoded
multipart/form-data
text/plain
注:只有同時滿足以上兩個條件時,才是簡單請求,否則為非簡單請求
CORS預(yù)檢請求又是什么?前面說了這么多預(yù)檢請求,我們來講一講什么是預(yù)檢請求:
如果我們在client端發(fā)送請求時,例如:
// 原生 var invocation = new XMLHttpRequest(); invocation.setRequestHeader("X-EXAMPLE", "xixihaha"); invocation.setRequestHeader("Content-Type", "application/xml"); // axios axios.defaults.headers["X-EXAMPLE"] = "xixihaha"; axios.defaults.headers["Content-Type"] = "application/xml";
POST 請求發(fā)送一個 XML 文檔,該請求包含了一個自定義的請求首部字段(X-EXAMPLE: xixihaha)。另外,該請求的 Content-Type 為 application/xml。因此,該請求需要首先發(fā)起“預(yù)檢請求”。
server端 的HTTP頭設(shè)置
Access-Control-Allow-Origin: "具體的域名" Access-Control-Allow-Methods: POST, GET, OPTIONS // 可包含的參數(shù) Access-Control-Allow-Headers: X-PINGOTHER, Content-Type // 允許的首部字段 Access-Control-Max-Age: 86400
非簡單請求和簡單請求無異,如果瀏覽器的預(yù)檢請求被服務(wù)器接受,則發(fā)送實際請求,未被接受則拒絕請求。
其他跨域不止于此
JSONP
動態(tài)創(chuàng)建script標簽,然后利用script的src 不受同源策略約束來跨域獲取數(shù)據(jù)
function addScriptTag() { var script = document.createElement("script"); script.src = "http://foo.example?callback=handleResponse"; document.body.appendChild(script); } function handleResponse() { console.log("跨域數(shù)據(jù)"); };
以下跨域方案不做過多解釋
上文提到的 postMessage()nginx轉(zhuǎn)發(fā),即架設(shè)服務(wù)器代理
window.name參考
阮一峰的網(wǎng)絡(luò)日志
MDN web docs CORS
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102460.html
同源策略:同源策略/SOP(Sameoriginpolicy)是一類承諾,由Netscape公司1995年引進電腦瀏覽器,這是電腦瀏覽器最關(guān)鍵也最基本安全配置,如今全部適用JavaScript瀏覽器都是會使用這種對策。假如缺乏了同源策略,電腦瀏覽器很容易受XSS、CSFR等進攻?! ⊥诰褪侵?quot;協(xié)議書+網(wǎng)站域名+服務(wù)器端口"三個同樣,就算兩種不同的域名跳轉(zhuǎn)相同ip詳細地址,...
跨域 要知道在請求后臺接口遇到Access-Control-Allow-Origin時,這就表明跨域了?! ∈紫冉忉尶缬颍且驗闉g覽器的同源策略所導(dǎo)致,同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,同源是指:域名、協(xié)議、端口相同 解決跨域常用方法: 一、VUE中常用proxy來解決跨域問題 1、在vue.config.js中設(shè)置如下代碼...
摘要:此時完成的跨域代理配置僅僅是在開發(fā)環(huán)境下生效,到了生產(chǎn)環(huán)境下如果是放到服務(wù)器上則還需要借助的反向代理來進行跨域的代理??缬?指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本,它是由瀏覽器的同源策略造成的,是瀏覽器對 JavaScript 施加的安全限制。同源就是指 域名,協(xié)議,端口 均相同。兩個網(wǎng)域若 域名、協(xié)議、端口 任一不同則二者的通信就出現(xiàn)了跨域問題,前端的跨域問題普通存在于兩個階段,一個是開發(fā)環(huán)境...
摘要:是上一次加載資源時,服務(wù)器返回的,是對該資源的一種唯一標識,只要資源有變化,就會重新生成。同源限制如果非同源以下三種行為將受到限制和無法讀取。Js相關(guān)執(zhí)行環(huán)節(jié)和作用域執(zhí)行環(huán)節(jié)定義了函數(shù)或者變量可以訪問的其它數(shù)據(jù),決定了他們各自的行為。每個執(zhí)行環(huán)境都有一個與之關(guān)聯(lián)的變量對象,在環(huán)境中定義的所有變量和函數(shù)都保存在這個變量中,并且是我們無法訪問。每個函數(shù)都有自己的執(zhí)行環(huán)境,當執(zhí)行流進入一個函數(shù)的時...
閱讀 1246·2021-09-04 16:41
閱讀 2403·2021-09-02 10:18
閱讀 917·2019-08-29 16:40
閱讀 2614·2019-08-29 16:14
閱讀 898·2019-08-26 13:41
閱讀 1299·2019-08-26 12:24
閱讀 731·2019-08-26 10:24
閱讀 2869·2019-08-23 17:54