jsonp原理
一些标签本身具备跨域能力,
jsonp利用了<script>标签的src属性实现跨域,发送GET请求
风险
- 回调函数的函数名可以自定义,如果callbackName为另一个script标签,将会导致后面的恶意代码执行
- CSRF攻击:jsonp跨域发送请求,通过callback获取用户的隐私信息。解决:设置token
实现思路
- 动态创建一个script标签
- 设置script标签的src属性为url,设置回调函数处理返回的数据
实现步骤
-
定义一个jsonp函数,传入参数为url,请求携带参数params,回调函数名callbackName
-
jsonp函数内部需要完成两件事情,一个是拼接url,params,callbackName为完整路径,二是返回一个promise对象
-
promise中完成jsonp跨域
1)创建一个script标签
2)将拼接好的url设置为script标签的src属性
3)将script标签添加到dom中
4)处理callback执行结果,请求成功后删除添加的script
代码实现
//手写jsonp,函数中传入参数,url,params,callbackName
function jsonp({ url, params, callbackName }) {
//定义一个函数拼接url字符串
function getUrl() {
//遍历params对象中的键值对,拼接到callbackName前面
let dataSrc = ''
for (let key in params) {
if (params.hasOwnProperty(key)) {
dataSrc += `${key}=${params[key]}&`
}
}
//拼接callback
dataSrc+=`callBack=${callbackName}`
//拼接url
return `${url}?${dataSrc}`
}
return new Promise((resolve,reject)=>{
//首先创建一个script标签
var scriptEle = document.createElement('script');
//修改script标签的src属性
scriptEle.src = getUrl;
//把节点放到文档中
document.body.appendChild(scriptEle);
//处理回调函数
window[callbackName] = data=>{
resolve(data);
//删除script标签
document.removeChild(scriptEle);
}
})
}