持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
jsonp
实现跨域的方式有有很多种,这里我们介绍 jsonp 的方式:
通过 script 标签,返回一个函数,函数名由用户传入。
我们以百度为示例,在百度搜索框输入 a 后,通过控制台拿到它的请求。删除掉无用参数后,请求的 url 为:https://www.baidu.com/sugrec?prod=pc&wd=a&cb=show
将其丢进浏览器,可以看到返回的内容如下:(注意,这里我将 cb 的值改为了 show)
调用jsonp请求
以上面的请求为例,假设我们的页面需要请求上面的搜索内容
通过该 url 返回的内容可以发现,其实它返回的是一个函数 的执行,并且函数名为我们传参中 cb 的值(show)
那么我们其实就可以将这个请求作为一个 show 函数的调用,只需要在我们自己的代码中编写 show 函数即可。
<body>
<script>
// 这里定义函数,会在下面的script请求中执行
function show(data) {
// data会由下面的请求传入
console.log(data)
}
</script>
<!-- 请求回来后,就是一个函数执行 -->
<scirpt src="https://www.baidu.com/sugrec?prod=pc&wd=a&cb=show""></scirpt>
</body>
上面的代码,等同于:
<body>
<script>
function show(data) {
console.log(data)
}
show({q: "a", p: false, g: [{"type":"sug","sa":"s_1","q":"a站"},{"type":"sug","sa":"s_2","q":"a股"} ...]})
</script>
</body>
这样就是一个完整的 jsonp 调用了。
封装jsonp请求
上面的代码调用是原始的 jsonp 调用,虽然能完成功能,但是并不方便使用,我们需要将其封装的更为易用
- 使用方式
// 类似 jquery 中的使用方法
jsonp({
url: "https://www.baidu.com/sugrec",
params: { prod: "pc", wd: "a" },
cb: "show"
}).then(data => {
console.log(data)
})
- 实现jsonp 函数
function jsonp({ url, params, cb }) {
// 返回一个 Promise 对象(因为加载url是异步的)
return new Promise((resolve, reject) => {
// 通过动态创建script标签的方式,使用jsonp
let script = document.createElement("script")
window[cb] = function(data) {
resolve(data);
// 用完script后删除
document.body.removeChild(script)
}
// 组装参数
params = {...params, cb} // wd=b&cb=show
let arrs = []
for(let key in params) {
arrs.push(`${key}=${params[key]}`)
}
script.src = `${url}?${arrs.join("&")}`
// 一定要放入页面中,才会进行加载
document.body.appendChild(script)
})
}
我们可以看到控制台打印出了 data 的内容
完整代码如下
<body>
<script>
function jsonp({ url, params, cb }) {
return new Promise((resolve, reject) => {
let script = document.createElement("script")
window[cb] = function(data) {
resolve(data);
// 用完script后删除
document.body.removeChild(script)
}
params = {...params, cb} // wd=b&cb=show
let arrs = []
for(let key in params) {
arrs.push(`${key}=${params[key]}`)
}
script.src = `${url}?${arrs.join("&")}`
document.body.appendChild(script)
})
}
jsonp({
url: "https://www.baidu.com/sugrec",
params: { prod: "pc", wd: "a" },
cb: "show"
}).then(data => {
console.log(data)
})
</script>
</body>