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