同源策略
就是瀏覽器規(guī)定的只有相同的協(xié)議,相同的域名,相同的端口,滿足以上條件才能讀取對方的資源,否則不能。
什么是跨域?跨域有幾種實(shí)現(xiàn)形式
跨域:就是通過一些處理,可以讓不同域名之間能夠相互讀取資源
跨域有4種實(shí)現(xiàn)形式:
1.JSONP:html可以加載另一個(gè)域名的js文件,然后我們可以利用這個(gè)功能,后端可以將數(shù)據(jù)整合成為js格式的字符串讓前端加載,加載好后,前端通過函數(shù)將其數(shù)據(jù)華為己用。
2.COSR:跨域資源共享(Cross-Origin Resource Sharing),在后端設(shè)置cosr屬性,res.header(''Access-Content-Allow-Origin","同意訪問的url"),相應(yīng)的url就能訪問這個(gè)后端服務(wù)器了。
3.降域:2者要設(shè)置document.domain='"' 訪問的前后都要降域并且2者都要有同一個(gè)基礎(chǔ)域名。
4.passMassage:window下的一個(gè)方法,window.passMessage(值,傳遞的地址)
JSONP 的原理
html可以加載另一個(gè)域名的js文件,然后我們可以利用這個(gè)功能,后端可以將數(shù)據(jù)整合成為js格式的字符串讓前端加載,加載好后,前端通過函數(shù)將其數(shù)據(jù)華為己用。
例如
$('.change').addEventListener('click', function(){
var script = document.createElement('script');
script.src = 'http://127.0.0.1/getNews?callback=appendHtml';
document.head.appendChild(script);
document.head.removeChild(script);
})
function appendHtml(news){
var html = "";
for(var i = 0; i<news.length;i++){
html = '<li>'+news[i]+'</li>'
}
$(.news).innerHTML = html;
}
以上是前端,下面是后端
app.get("getNews",function(){
var new = [x,x,x];
var data = [];
for (var i = 0; i<3; i++){
var index = parseInt(Math.random()*news.length);
data.push(new[index]);
news.splice(index,1);
}
var cb = req.query.callback;
if(req.query.callback){
res.send(cb + '('+ JSON.stringify(data) + ')')
}else{res.send(data)}
})
CORS是什么
跨域資源共享(Cross-Origin Resource Sharing),分為簡單請求和復(fù)雜請求,簡單請求在后端設(shè)置cosr屬性,res.header(''Access-Content-Allow-Origin","同意訪問的url"),相應(yīng)的url就能訪問這個(gè)后端服務(wù)器了。
復(fù)雜請求:
表面上看起來和簡單請求使用上差不多,但實(shí)際上瀏覽器發(fā)送了不止一個(gè)請求。其中最先發(fā)送的是一種"預(yù)請求",此時(shí)作為服務(wù)端,也需要返回"預(yù)回應(yīng)"作為響應(yīng)。預(yù)請求實(shí)際上是對服務(wù)端的一種權(quán)限請求,只有當(dāng)預(yù)請求成功返回,實(shí)際請求才開始執(zhí)行。預(yù)請求以O(shè)PTIONS形式發(fā)送,當(dāng)中同樣包含域,并且還包含了兩項(xiàng)CORS特有的內(nèi)容:
Access-Control-Request-Method – 該項(xiàng)內(nèi)容是實(shí)際請求的種類,可以是GET、POST之類的簡單請求,也可以是PUT、DELETE等等。
Access-Control-Request-Headers– 該項(xiàng)是一個(gè)以逗號分隔的列表,當(dāng)中是復(fù)雜請求所使用的頭部。
顯而易見,這個(gè)預(yù)請求實(shí)際上就是在為之后的實(shí)際請求發(fā)送一個(gè)權(quán)限請求,在預(yù)回應(yīng)返回的內(nèi)容當(dāng)中,服務(wù)端應(yīng)當(dāng)對這兩項(xiàng)進(jìn)行回復(fù),以讓瀏覽器確定請求是否能夠成功完成。
復(fù)雜請求的部分響應(yīng)頭及解釋如下:
Access-Control-Allow-Origin(必含) – 和簡單請求一樣的,必須包含一個(gè)域。
Access-Control-Allow-Methods(必含) – 這是對預(yù)請求當(dāng)中Access-Control-Request-Method的回復(fù),這一回復(fù)將是一個(gè)以逗號分隔的列表。盡管客戶端或許只請求某一方法,但服務(wù)端仍然可以返回所有允許的方法,以便客戶端將其緩存。
Access-Control-Allow-Headers(當(dāng)預(yù)請求中包含Access-Control-Request-Headers時(shí)必須包含) – 這是對預(yù)請求當(dāng)中Access-Control-Request-Headers的回復(fù),和上面一樣是以逗號分隔的列表,可以返回所有支持的頭部。這里在實(shí)際使用中有遇到,所有支持的頭部一時(shí)可能不能完全寫出來,而又不想在這一層做過多的判斷,沒關(guān)系,事實(shí)上通過request的header可以直接取到Access-Control-Request-Headers,直接把對應(yīng)的value設(shè)置到Access-Control-Allow-Headers即可。
Access-Control-Allow-Credentials(可選) – 和簡單請求當(dāng)中作用相同。
Access-Control-Max-Age(可選) – 以秒為單位的緩存時(shí)間。預(yù)請求的的發(fā)送并非免費(fèi)午餐,允許時(shí)應(yīng)當(dāng)盡可能緩存。
一旦預(yù)回應(yīng)如期而至,所請求的權(quán)限也都已滿足,則實(shí)際請求開始發(fā)送。
通caniuse.com得知,目前大部分Modern瀏覽器已經(jīng)支持完整的CORS,但I(xiàn)E直到IE11才完美支持,所以對于PC網(wǎng)站,還是建議采用其他解決方案,如果僅僅是移動(dòng)端網(wǎng)站,大可放心使用。
根據(jù)視頻里的講解演示三種以上跨域的解決方式
1.JSONP:題目三已有
2.cors:http://js.jirengu.com/mucayijibe/1/edit?html,js,output
3.降域:http://js.jirengu.com/tapafaneni/1/edit?html,output
4.passMassage:http://js.jirengu.com/jawufeyile/1/edit?html,output