作為一個(gè)前端求職者一定不會(huì)陌生跨域這個(gè)詞,動(dòng)不動(dòng)面試中就會(huì)被問(wèn)到。但是很疑惑的是,作為一個(gè)前端,我真的不知道什么是跨域啊,工作中又沒(méi)遇到跨域的問(wèn)題啊。
很奇怪啊,為什么我工作中從來(lái)沒(méi)用到的東西老是問(wèn)我。不要感到奇怪,為什么我沒(méi)遇到跨域的問(wèn)題?因?yàn)槟氵M(jìn)項(xiàng)目的時(shí)候有人已經(jīng)把這個(gè)問(wèn)題解決了啊。
那前端還會(huì)問(wèn)了,既然有人解決了,我怎么沒(méi)在代碼中找到怎么解決的啊?答案是,因?yàn)槭窃诤蠖伺渲玫陌。–ORS-跨域資源共享)。
為什么會(huì)有跨域的問(wèn)題
既然你誠(chéng)心誠(chéng)意問(wèn)了,那我就正兒八經(jīng)的回答你??缬蚴菫榱税踩?!
感覺(jué)這個(gè)回答沒(méi)什么意義吧,因?yàn)榛卮鹌饋?lái)很復(fù)雜啊。就不具體介紹了,有興趣的可以了解一下瀏覽器的同源策略 和 為什么給你設(shè)置重重障礙?講一講Web開(kāi)發(fā)中的跨域——二、為什么不讓我跨域
簡(jiǎn)單看下這個(gè)表,相對(duì)于 http://store.company.com/dir/page.html 同源檢測(cè)的示例:
| URL | 結(jié)果 | 原因 |
|---|---|---|
http://store.company.com/dir2/other.html |
成功 | |
http://store.company.com/dir/inner/another.html |
成功 | |
https://store.company.com/secure.html |
失敗 | 不同協(xié)議 ( https和http ) |
http://store.company.com:81/dir/etc.html |
失敗 | 不同端口 ( 81和80) |
http://news.company.com/dir/other.html |
失敗 | 不同域名 ( news和store ) |
簡(jiǎn)單來(lái)說(shuō)就是協(xié)議、端口、域名有任何一個(gè)不同都會(huì)導(dǎo)致同源檢測(cè)失敗。
解決方案
方案一:JSONP
為什么叫 JSONP 呢?JSONP 的全稱(chēng)是 JSON with Padding,填充式 JSON 或 參數(shù)式JSON。JSONP 由兩部分構(gòu)成:回調(diào)函數(shù)和數(shù)據(jù)。
首先回調(diào)函數(shù)長(zhǎng)這樣子:
function handleResponse(response) {
console.log(response)
}
例如點(diǎn)擊按鈕時(shí),發(fā)一個(gè)請(qǐng)求獲取 books 數(shù)據(jù):
function handleClick() {
let script = document.createElement("script");
script.src = "http://books?callback=handleResponse";
script.async = true;
script.type = "text/javascript";
document.body.appendChild(script);
}
當(dāng)點(diǎn)擊按鈕時(shí),調(diào)用 handleClick 函數(shù)。此函數(shù)做的事兒就是動(dòng)態(tài)的添加一個(gè) <script/> 標(biāo)簽,url 就是獲取 books 的接口。url 中有一個(gè) callback 的參數(shù),其值就是 handleResponse 函數(shù)。請(qǐng)求回來(lái)后就會(huì)調(diào)用 handleResponse函數(shù),這樣子我們就拿到了數(shù)據(jù)。
JSONP 優(yōu)點(diǎn)是使用簡(jiǎn)單,兼容性也不錯(cuò),但是只限于 get 請(qǐng)求。
方案二:CORS
CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱(chēng)是"跨域資源共享"(Cross-origin resource sharing)。CORS 需要瀏覽器和后端都支持,現(xiàn)在瀏覽器都支持(IE10以上),那么就需要后端配置一下了。
只要后端設(shè)置 Access-Control-Allow-Origin 就可以實(shí)現(xiàn)跨域了。需要了解詳情的可以參考跨域資源共享 CORS 詳解
方案三:document.domain
此方案只適用于二級(jí)域名相同的情況下,比如 pageA.crossdomin.com 和 pageB.crossdomin.com。只需要在頁(yè)面設(shè)置 document.domin = 'crossdomin.com',表示二級(jí)域名相同就可以了。
參考
當(dāng)然,還有一下方案可以實(shí)現(xiàn)跨域,就不一一詳細(xì)說(shuō)明了。
- postMessage
- 其他跨域技術(shù) —— JavaScript 高級(jí)程序設(shè)計(jì)(第三版)P586
參考文章: