- 什么是同源策略
- 同源的定義: 源:協議/版本號+域名+端口號。只有兩個源完全一致,既稱為同源。
- 同源策略的意義:同源策略是瀏覽器強制規定的,主要是用與保護用戶的隱私。
比如黑客網站的js通過發送ajax請求,請求網站的用戶信息,如果沒有同源策略,由于黑客網站的請求和本網站的請求基本是一樣的(只有referer不一樣)。如果后臺沒有檢查referer,那么黑客將可以訪問到用戶數據。黑客的請求可以成功發送,但是瀏覽器不會把數據給他 - 同源策略限制的是數據訪問,我們引用js、css、圖片的時候,并不知道其內容,只是在引用。
- 如何跨域
2.1 CORS
語法很簡單,在響應頭加上Access-Conrtol-Allow-Orign:允許被訪問的源
但是不兼容ie
2.2 JSONP
JSONP是為了兼容ie所采用的跨域方法。
舉例說明:
- a網站想訪問b網站的user.json文件,b網站也同意了,但是在ie上面是無法跨域的。
- 但是a網站是可以通過script標簽引用b網站的js文件的,因此可以把b網站的user.json文件套一層js。
- 具體做法就是:b網站新建一個user.js文件,文件里面只寫
windows.xxx={{data}}
。然后服務器增加一個/user.js的路由,獲取本地user.js和user.json的數據,并將它們轉為字符串把然后user.js里面的{{data}}和user.json的字符串replace,因此最后發送的響應體就是window.xxx=user.json.toString()
。
*這時候b網站只需要把路徑告訴a網站,以及xxx的具體值,a網站就可以訪問到b網站的user.json數據了。 - 缺點是如果路徑還有變量名被其他網站盜取了,那么其他網站也能訪問到該數據,改進方法就是通過設置響應頭referer,實現JSOPN定向分享。
2.3 JSONP的優化與封裝
優化的第一步就是不要把變量名xxx寫死:
- 還是上面那個例子,首先a網站生成一個隨機數,然后把隨機數掛在windows上面:
windows[random]
,然后在把fileNane=random放在查詢參數上面傳給網站b。 - 網站b通過查詢參數,能得到a網站傳遞過來的隨機數,這時候修改user.js文件,改為
windows[{{xxx}}]={{data}}
,然后在把{{xxx}}
repalce為所得到的隨機數即可。
其次,拿到數據后,可以把該script標簽刪掉。
監聽script的onload事件,回調函數寫script.remove()
把JSOPN封裝成函數jsonp(url).then()
const jsonp=(url)=>{
return new Promise((resolve,reject)=>{
const random=Math.random();
const script=document.createElement("script");
script.src=`${url}?fileName=${random.toString()}`;
script.onload=()=>{
resolve(window[random]);
script.remove();
};
script.onerror=()=>{
reject();
};
document.body.appendChild(script);
})
}
- 面試回答JSONP
跨域的時候由于當前瀏覽器不支持CORS,必須選擇其它方式進行跨域。這時候只能用script標簽引用一個js文件,js文件會執行一個回掉,或者會對某個約定好的全局變量進行賦值,這時候就能夠訪問到跨域數據。
優點:兼容ie,可以跨域
缺點:由于他是script,所以不能像ajax那樣讀到精確的響應內容,只能知道成功或者失敗。并且只能發get請求。