簡(jiǎn)述
[定義]
- 什么是跨域,CORS是什么?
跨域資源共享(CORS) 是一種機(jī)制,它使用額外的 HTTP 頭來(lái)告訴瀏覽器 讓運(yùn)行在一個(gè) origin (domain) 上的Web應(yīng)用被準(zhǔn)許訪問來(lái)自不同源服務(wù)器上的指定的資源。
當(dāng)一個(gè)資源從與該資源本身所在的服務(wù)器不同的域、協(xié)議或端口請(qǐng)求一個(gè)資源時(shí),資源會(huì)發(fā)起一個(gè)跨域 HTTP 請(qǐng)求。
(其實(shí)瀏覽器成功發(fā)送請(qǐng)求并拿回了數(shù)據(jù) 只是瀏覽器的同源策略 禁止了獲取 )
1-1. 所謂的三項(xiàng)必須相同,否則引起跨域
協(xié)議 域名 端口號(hào)
https:// localhost :8080
協(xié)議 :
window.location.protocol
端口號(hào) :
window.location.port
- App請(qǐng)求接口類似于C/S不存在跨域問題。
[表現(xiàn)]
同源策略限制了一下行為:
1.Cookie、LocalStorage 和 IndexDB 無(wú)法讀取
2.DOM 和 JS 對(duì)象無(wú)法獲取
3.Ajax請(qǐng)求發(fā)送不出去
-
為什么我們可以使用JSONP的方式,來(lái)解決跨域問題?
3-1. 主要利用了標(biāo)簽上src的開放性原則,
以img為例,我們可以在 其屬性src上設(shè)置一個(gè)外網(wǎng)的遠(yuǎn)程圖片,而不會(huì)引起跨域
以script為例,可以引用外網(wǎng)CDN上的jquery遠(yuǎn)程資源,提高JS加載速度,而不會(huì)跨域
3-2. 在script標(biāo)簽上引入的外部資源,如js文件、txt文件、PHP文件,只要其內(nèi)部語(yǔ)法拼接為一個(gè)模仿javascript語(yǔ)言的字符串,script引入它后,就可以按照js代碼來(lái)執(zhí)行因此,我們可以利用如上兩點(diǎn),將函數(shù)名,params參數(shù)以get方式拼接在這個(gè)外鏈后面,
后臺(tái)再返回?cái)?shù)據(jù)的時(shí)候,返回一個(gè)函數(shù)執(zhí)行操作,函數(shù)名就是get方式傳遞過去的參數(shù)
后臺(tái)要返回要傳遞的真正數(shù)據(jù),則通過函數(shù)形參的形式,傳遞上去。
這樣,在前端定義這個(gè)函數(shù)的聲明后,在后臺(tái)返回代碼會(huì)可以調(diào)用前端的函數(shù),而參數(shù)也被我們拿到了,那就是后臺(tái)真正要傳遞的數(shù)據(jù)
至此完成了一個(gè)JSONP的數(shù)據(jù)傳遞過程
前端
//傳遞參數(shù)
var vin='lgbh12e08fy367896';
//自定義的jsonp回調(diào)函數(shù)
window.testCallBack = function(data){
//處理回調(diào)
}
$("#getcarinfo").click(function(){
$.ajax({
type: "get",
async: false,
url: "http://www.runoob.com/try/ajax/jsonp.php", //示例demo的PHP環(huán)境接口
//可以帶參數(shù)傳到后臺(tái)
//url: "http://wenhao2018.hello2game.com/game/getDailei?bundleid=id.id.id&companycode=doctordai",
data: { vin: vin },
dataType: "jsonp",
jsonp: "jsoncallback", //傳遞給請(qǐng)求處理程序或頁(yè)面的,用以獲得jsonp回調(diào)函數(shù)名的參數(shù)名(默認(rèn)為:callback)
//自定義回調(diào)
//jsonpCallback: "testCallBack", //自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動(dòng)生成的隨機(jī)函數(shù)名
success: function (json) { //在此之前若沒有定義回調(diào)函數(shù)success_jsonpCallback2則執(zhí)行下面的代碼
alert(json[0]);
},
error: function () {
alert('fail');
}
});
});
后端
<?php
header('Content-type: application/json');
//獲取回調(diào)函數(shù)名
$jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']);
//json數(shù)據(jù)
$json_data = '["customername1","customername2"]';
//輸出jsonp格式的數(shù)據(jù)
echo $jsoncallback . "(" . $json_data . ")";
?>
時(shí)代局限以及不足

1.必須為GET方式傳輸
2.安全問題,返回字符串可能被惡意篡改
3.傳輸數(shù)據(jù)大小限制本身問題 --- IE瀏覽器4KB、 主流瀏覽器5MB
4.在IE中存在緩存數(shù)據(jù)不同步的情況(二次訪問,會(huì)優(yōu)先走緩存,而不是服務(wù)器)
解決方法:
4-1. 在get請(qǐng)求的url中增加隨機(jī)標(biāo)識(shí)(推薦)
4-2. 在axios中設(shè)置header,ajax可以用setRequestHeader方法(推薦)
const api = axios.create({
// ...
headers: {
'Cache-Control': 'no-cache'
}
// ...
})
5.溝通成本,需要后臺(tái)人員配合
等....