前端開發(fā)中,常常需要進(jìn)行跨域請(qǐng)求寂玲。既然提到跨域爹橱,首先我們的知道什么是“同源策略”滴肿。
同源策略限制從一個(gè)源加載的文檔或腳本如何與來自另一個(gè)源的資源進(jìn)行交互。這是一個(gè)用于隔離潛在惡意文件的關(guān)鍵的安全機(jī)制队询。
如果協(xié)議派桩,端口(如果指定了一個(gè))和域名對(duì)于兩個(gè)頁(yè)面是相同的,則兩個(gè)頁(yè)面具有相同的源蚌斩。
同一個(gè)源內(nèi)铆惑,資源的訪問是很自由的。就跟在自己家中送膳,想開冰箱開冰箱员魏,想干啥干啥。如果你想訪問不同源的資源叠聋,可就沒那么自由了撕阎,這就是跨域。
關(guān)于跨域碌补,常用的JSONP應(yīng)該都知道闻书。JSONP的原理是什么呢?我們來看看大神賀師俊的解釋:
很簡(jiǎn)單脑慧,就是利用<script>標(biāo)簽沒有跨域限制的“漏洞”(歷史遺跡捌敲肌)來達(dá)到與第三方通訊的目的。當(dāng)需要通訊時(shí)闷袒,本站腳本創(chuàng)建一個(gè)<script>元素坑律,地址指向第三方的API網(wǎng)址,并提供一個(gè)回調(diào)函數(shù)來接收數(shù)據(jù)(函數(shù)名可約定,或通過地址參數(shù)傳遞)晃择。 第三方產(chǎn)生的響應(yīng)為json數(shù)據(jù)的包裝(故稱之為jsonp冀值,即json padding),這樣瀏覽器會(huì)調(diào)用callback函數(shù)宫屠,并傳遞解析后json對(duì)象作為參數(shù)列疗。本站腳本可在callback函數(shù)里處理所傳入的數(shù)據(jù)。
可以知道JSONP就是個(gè)bug般的存在啊浪蹂,如果你是一個(gè)有潔癖的程序員回想說:這不合理抵栈,這部干凈。因此我們引出cors坤次。
那么古劲,什么是cors呢?
我們來看看互動(dòng)百科的解釋:
CORS(跨來源資源共享)是一份瀏覽器技術(shù)的規(guī)范缰猴,提供了Web服務(wù)從不同網(wǎng)域傳來沙盒腳本的方法产艾,以避開瀏覽器的同源策略,是JSONP模式的現(xiàn)代版滑绒。
維基百科的解釋(手動(dòng)谷歌):
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served.
這樣看來闷堡,其實(shí)嘛,cors就是一個(gè)規(guī)范疑故,機(jī)制缚窿,基于這個(gè)規(guī)范,不同源之間才可以請(qǐng)求資源焰扳。相當(dāng)于一個(gè)江湖規(guī)矩倦零,大家都按規(guī)矩來嘛不是?不講規(guī)矩吨悍?信不信小拳拳捶你扫茅。
所以呢,要想使用cors跨域訪問育瓜,你就得講規(guī)矩葫隙。下面我們來看看有哪些規(guī)矩。
跨域資源共享標(biāo)準(zhǔn)( cross-origin sharing standard )允許在下列場(chǎng)景中使用跨域 HTTP 請(qǐng)求:
- 前文提到的由 XMLHttpRequest 或 Fetch 發(fā)起的跨域 HTTP 請(qǐng)求躏仇。
- Web 字體 (CSS 中通過 @font-face 使用跨域字體資源), 因此恋脚,網(wǎng)站就可以發(fā)布
- TrueType 字體資源,并只允許已授權(quán)網(wǎng)站進(jìn)行跨站調(diào)用焰手。
- WebGL 貼圖
- 使用 drawImage 將 Images/video 畫面繪制到 canvas
樣式表(使用 CSSOM) - Scripts (未處理的異常)
cors中有個(gè)術(shù)語叫“簡(jiǎn)單請(qǐng)求”糟描,若請(qǐng)求滿足所有下述條件,則該請(qǐng)求可視為“簡(jiǎn)單請(qǐng)求”:
使用下列方法之一:
- GET
- HEAD
- POST
//注:僅當(dāng)POST方法的Content-Type值等于下列之一才算作簡(jiǎn)單請(qǐng)求
Content-Type :
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
之所以區(qū)分簡(jiǎn)單請(qǐng)求书妻,是因?yàn)閏ors需要處理一些“非簡(jiǎn)單請(qǐng)求”船响,這種特殊處理叫做“預(yù)檢請(qǐng)求”。大人物來了,總要提前準(zhǔn)備準(zhǔn)備吧见间,封路啥的blabla聊闯。
預(yù)檢請(qǐng)求的作用是提前獲知服務(wù)器是否允許該實(shí)際請(qǐng)求∶姿撸“預(yù)檢請(qǐng)求”的使用菱蔬,可以避免跨域請(qǐng)求對(duì)服務(wù)器的用戶數(shù)據(jù)產(chǎn)生未預(yù)期的影響。
一張圖可以清晰看到提前發(fā)送預(yù)檢請(qǐng)求的cors請(qǐng)求
可以打開控制臺(tái)看到我的博客系統(tǒng)中的
getArts
接口的預(yù)檢請(qǐng)求
Request Headers:
- Accept:/
- Accept-Encoding:gzip, deflate
- Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
- Access-Control-Request-Headers:content-type
- Access-Control-Request-Method:POST
- Host:47.52.5.137:3011
- Origin:http://47.52.5.137:4011
- Proxy-Connection:keep-alive
- Referer:http://47.52.5.137:4011/
- User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Response Header:
- Access-Control-Allow-Headers:content-type
- Access-Control-Allow-Methods:GET,PUT,POST,DELETE,HEAD,OPTIONS
- Access-Control-Allow-Origin:http://47.52.5.137:4011
- Date:Wed, 19 Jul 2017 02:31:10 GMT
- Proxy-Connection:Keep-alive
使用fetch發(fā)送cors跨域請(qǐng)求:
return fetch(url, {
method: 'POST',
// 設(shè)置這個(gè)header史侣,才能正確parse
headers: { 'Content-Type': 'application/json' },
mode: 'cors'
})
.then(response => response.json())
.then(data => {
console.log(data)
dispatch({
type: GET_ARTICLES,
articles: data.articles
})
})
cors在koa中的使用:
import cors from 'koa2-cors'
app.use(cors())
開源個(gè)人博客(歡迎star&fork)
github地址:https://github.com/wtfjun/chenxj-blog
在線地址:http://47.52.5.137:4011/
相關(guān)鏈接: