原理
主要就是利用了 script 標(biāo)簽的src沒(méi)有跨域限制來(lái)完成的。
執(zhí)行的過(guò)程
(1)前端定義一個(gè)解析函數(shù),例如 jsonpCallback=function(res){}
(2)通過(guò)params的形式包裝script的請(qǐng)求參數(shù),并且聲明執(zhí)行函數(shù)(如 cb=jsonpCallback)
(3)后端獲取到前端聲明的執(zhí)行函數(shù)(jsonpCallback),并以攜帶參數(shù)并且調(diào)用執(zhí)行函數(shù)的方式傳遞給前端
(4)前端zaiscript標(biāo)簽返回資源的時(shí)候就回執(zhí)行jsonpCallback,并以回調(diào)函數(shù)的方式拿到返回的數(shù)據(jù)了
優(yōu)缺點(diǎn)
缺點(diǎn):只能進(jìn)行GET請(qǐng)求,需要后臺(tái)配合
優(yōu)點(diǎn):兼容性好,在一些古老的瀏覽器中都可以運(yùn)行
簡(jiǎn)單使用
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>無(wú)標(biāo)題欄文檔</title>
</head>
<body>
<script type="text/javascript">
function jsonp(res) {
console.log(res) // 后臺(tái)返回的數(shù)據(jù)
}
</script>
// 這是后臺(tái)配合 整理出來(lái)的文件地址 我們加上callback 回調(diào)函數(shù)
<script src="https://xxx.com/aaa/aa/a.js?callback='jsonp'" type="text/javascript"></script>
</body>
</html>
上述就是利用<script>標(biāo)簽跨域get引入js腳本實(shí)現(xiàn)跨域請(qǐng)求即JSONP
封裝使用
<script>
function JSONP({ url, params = {},callbackKey = 'cb', callback }) {
// 定義本地的唯一callbackId,若是沒(méi)有的話(huà)則初始化為1
JSONP.callbackId = JSONP.callbackId || 1;
let callbackId = JSONP.callbackId;
// 把要執(zhí)行的回調(diào)加入到JSON對(duì)象中,避免污染window
JSONP.callbacks = JSONP.callbacks || [];
JSONP.callbacks[callbackId] = callback;
// 把這個(gè)名稱(chēng)加入到參數(shù)中: 'cb=JSONP.callbacks[1]'
params[callbackKey] = `JSONP.callbacks[${callbackId}]`;
// 得到'id=1&cb=JSONP.callbacks[1]'
const paramString = Object.keys(params).map(key => {
return `${key}=${encodeURIComponent(params[key])}`
}).join('&')
// 創(chuàng)建 script 標(biāo)簽
const script = document.createElement('script');
script.setAttribute('src', `${url}?${paramString}`);
document.body.appendChild(script);
// id自增,保證唯一
JSONP.callbackId++;
}
JSONP({
url: 'http://localhost:8080/api/jsonps',
params: {
a: '2&b=3',
b: '4'
},
callbackKey: 'cb',
callback (res) {
console.log(res)
}
})
JSONP({
url: 'http://localhost:8080/api/jsonp',
params: {
id: 1
},
callbackKey: 'cb',
callback (res) {
console.log(res)
}
})
</script>
上述就是利用<script>標(biāo)簽跨域get引入js腳本實(shí)現(xiàn)跨域請(qǐng)求 多個(gè)jsonp請(qǐng)求
?? encodeURI和encodeURIComment的區(qū)別
encodeURL()不會(huì)對(duì)本身屬于URI的字符進(jìn)行編碼,例如:“/”,“:”,“#”,“?”
encodeURIcomment() 則會(huì)對(duì)他發(fā)現(xiàn)的任何的非標(biāo)準(zhǔn)字符進(jìn)行編碼,同時(shí)使用decodeURIcomment()來(lái)解碼。