有以下幾個問題
- 什么是同源策略
- 什么是跨域压语?跨域有幾種實(shí)現(xiàn)形式
- JSONP 的原理是什么
- CORS是什么
我們先描述一個場景萨咕,小明是一個中國人谍憔,他想購買美國的商品跺撼,可是小明是用人民幣的病线,而美國是用美元的吓著,無法購買。怎么辦呢送挑,小明有以下幾種方法打到購買的目的:
- 找代購
- 建立中美自由貿(mào)易
- 用黃金購買
- 發(fā)布求購信息绑莺,等某個美國人主動聯(lián)系
這是一個瀏覽器跨域的比喻。
我們來回答開頭的4個問題惕耕。
1: 什么是同源策略
瀏覽器出于安全方面的考慮纺裁,只允許與本域下的接口交互。不同源的客戶端腳本在沒有明確授權(quán)的情況下司澎,不能讀寫對方的資源欺缘。
本域要同時滿足以下條件:
- 同協(xié)議:如都是http或者h(yuǎn)ttps
- 同域名:如都是
http://jirengu.com/a
和http://jirengu.com/b
- 同端口:如都是80端口
對應(yīng)上面場景里的情況就是,要使用同種貨幣才能購買挤安,比如小明可以在國內(nèi)用人民幣購買商品谚殊,因?yàn)閲鴥?nèi)是用人民幣交易的。
2: 什么是跨域蛤铜?跨域有幾種實(shí)現(xiàn)形式
跨域就是不同域下的接口交互嫩絮。(相當(dāng)于中國的小明想購買美國的商品。)
跨域的實(shí)現(xiàn)形式有
- jsonp (相當(dāng)于找代購)
- cors (相當(dāng)于建立中美自由貿(mào)易)
- 降域 (相當(dāng)于用黃金購買)
- postMessage (相當(dāng)于發(fā)布求購信息围肥,等某個美國人主動聯(lián)系)
3: JSONP 的原理是什么
Web頁面上調(diào)用js文件時不受跨域的影響(不僅如此剿干,我們還發(fā)現(xiàn)凡是擁有”src”這個屬性的標(biāo)簽都擁有跨域的能力,比如<script>穆刻、<img>置尔、<iframe>
);
jsonp就是利用了<script src="xxxx"> </script>
這個標(biāo)簽不受跨域影響氢伟。
(<script> 相當(dāng)于代購)
話不多說榜轿,直接上代碼解釋篮愉,看注釋:
前端代碼
<script>
$('.change').addEventListener('click', function(){ //給元素綁定事件
var script = document.createElement('script'); //點(diǎn)擊事件后,創(chuàng)造一個script元素
script.src = 'http://127.0.0.1/getNews?callback=appendHtml';
/*設(shè)置script元素的src屬性差导,?前面的是協(xié)議猪勇,域名设褐,接口。
泣刹?后面是用戶傳遞的一個callback參數(shù)
*/
document.head.appendChild(script); //把script元素添加到頁面上
})
function appendHtml(news){ // 聲明包裹數(shù)據(jù)的函數(shù)
var html = '';
for( var i=0; i<news.length; i++){
html += '<li>' + news[i] + '</li>';
}
console.log(html);
$('.news').innerHTML = html;
}
function $(id){
return document.querySelector(id);
}
</script>
后端router.js
app.get('/getNews', function(req, res) {
var news = [
"第11日前瞻:中國沖擊4金 博爾特再戰(zhàn)200米羽球",
"正直播柴飚/洪煒出戰(zhàn) 男雙力爭會師決賽",
"女排將死磕巴西助析!郎平安排男陪練模仿對方核心",
"沒有中國選手和巨星的110米欄 我們還看嗎?",
"中英上演奧運(yùn)金牌大戰(zhàn)",
"博彩賠率挺中國奪回第二紐約時報:中國因?qū)κ址幎鴣G失的獎牌最多",
"最“出柜”奧運(yùn)椅您?同性之愛閃耀里約",
"下跪拜謝與洪荒之力一樣 都是真情流露"
]
var data = [];
for (var i = 0; i < 3; i++) {
var index = parseInt(Math.random() * news.length);
data.push(news[index]);
news.splice(index, 1);
}
var cb = req.query.callback; //獲取callback參數(shù)內(nèi)的值
if (cb) {
res.send(cb + '(' + JSON.stringify(data) + ')');
//如果callback參數(shù)的值存在外冀,就用它做函數(shù)名包裹數(shù)據(jù),再發(fā)送
} else {
res.send(data);
//如果沒有callback參數(shù)掀泳,數(shù)據(jù)就直接發(fā)送
}
})
jsonp就是獲取一段代碼雪隧,用js去執(zhí)行,
前端向后端發(fā)送一個參數(shù)员舵,后端用這個參數(shù)封裝數(shù)據(jù)脑沿,發(fā)回來,前端再執(zhí)行
jsonp需要前后端配合马僻,后端同意才能跨域庄拇,沒有安全問題
4: CORS是什么
CORS:全稱為 Cross Origin Resource Sharing,跨域資源共享韭邓,是一種 ajax 跨域請求資源的方式措近,支持現(xiàn)代瀏覽器,IE支持10以上女淑。
CORS的實(shí)現(xiàn)方式是瞭郑,在后端的響應(yīng)頭添加一個
Access-Control-Allow-Origin
屬性,屬性的值是允許的域名鸭你。它的好處是前端的請求就是ajax凰浮,不需要修改,只要后端開訪問權(quán)限即可苇本,很方便袜茧。
代碼實(shí)例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>news</title>
<style>
.container {
width: 900px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<ul class="news">
<li>第11日前瞻:中國沖擊4金 博爾特再戰(zhàn)</li>
<li>男雙力爭會師決賽 </li>
<li>女排將死磕巴西!</li>
</ul>
<button class="change">換一組</button>
</div>
<script>
$('.change').addEventListener('click', function() {
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://b.jrg.com:8080/getNews', true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
appendHtml(JSON.parse(xhr.responseText))
}
}
window.xhr = xhr
})
function appendHtml(news) {
var html = '';
for (var i = 0; i < news.length; i++) {
html += '<li>' + news[i] + '</li>';
}
//console.log(html);
$('.news').innerHTML = html;
}
function $(id) {
return document.querySelector(id);
}
</script>
</body>
</html>
app.get('/getNews', function(req, res){
var news = [
"第11日前瞻:中國沖擊4金 博爾特再戰(zhàn)200米羽球",
"正直播柴飚/洪煒出戰(zhàn) 男雙力爭會師決賽",
"女排將死磕巴西瓣窄!郎平安排男陪練模仿對方核心",
"沒有中國選手和巨星的110米欄 我們還看嗎笛厦?",
"中英上演奧運(yùn)金牌大戰(zhàn)",
"博彩賠率挺中國奪回第二紐約時報:中國因?qū)κ址幎鴣G失的獎牌最多",
"最“出柜”奧運(yùn)?同性之愛閃耀里約",
"下跪拜謝與洪荒之力一樣 都是真情流露"
]
var data = [];
for(var i=0; i<3; i++){
var index = parseInt(Math.random()*news.length);
data.push(news[index]);
news.splice(index, 1);
}
res.header("Access-Control-Allow-Origin", "*");
/*后端如果允許訪問數(shù)據(jù)俺夕,就在響應(yīng)頭中添加一個參數(shù)Access-Control-Allow-Origin裳凸,
后面的參數(shù)值為允許的域名贱鄙,這里 * 表示允許所有人訪問,如果只想允許個別人訪問姨谷,就單獨(dú)設(shè)置
*/
res.send(data);
})