内容简介:JSONP 实现
JSONP 是解决跨域问题的一种方案,不同于 JSON,其并不是一种数据交换格式,而只是一种绕过跨域的技巧。
JSONP
JSONP 的原理非常简单,为了克服跨域问题,利用没有跨域限制的 script 标签加载预设的 callback 将内容传递给 js。一般来说我们约定通过一个参数来告诉服务器 JSONP 返回时应该调用的回调函数名,然后拼接出对应的 js。已微博 API 为例,这个参数名是 _cb 。
我们可以写一个简单的版本:
function JSONP({
url,
params,
callbackKey,
callback
}) {
// 在参数里制定 callback 的名字
params = params || {}
params[callbackKey] = 'jsonpCallback'
// 预留 callback
window.jsonpCallback = callback
// 拼接参数字符串
const paramKeys = Object.keys(params)
const paramString = paramKeys
.map(key=> `${key}=${params[key]}`)
.join('&')
// 插入 DOM 元素
const script = document.createElement('script')
script.setAttribute('src', `${url}?${paramString}`)
document.body.appendChild(script)
}
JSONP({
url: 'http://s.weibo.com/ajax/jsonp/suggestion',
params: {
key: 'test',
},
callbackKey: '_cb',
callback(result) {
console.log(result.data)
}
})
会在命令行看到 ["TEST", "特殊泰帮承"] ,注意这里新浪微博的 API 只支持 HTTP,所以我们只能在 HTTP 页面上测试。
同时进行多个请求
上面的流程有一个问题,就是在只有一个 JSONP 调用时它工作的很正常,但是当出现两个或者以上的请求,回调函数就会被覆盖,这样会出现混乱。为了解决这个问题,我们需要对所有的回调函数进行编码,并且在调用时告诉后端对应的独一无二的编号。
除此之外,污染全局空间显然是个不明智的选择,这个问题解决起来倒是非常简单,扔到 JSONP.xxx 下即可。
function JSONP({
url,
params,
callbackKey,
callback
}) {
// 唯一 id,不存在则初始化
JSONP.callbackId = JSONP.callbackId || 1
params = params || {}
// 传递的 callback 名,和下面预留的一致
params[callbackKey] = `JSONP.callbacks[${JSONP.callbackId}]`
// 不要污染 window
JSONP.callbacks = JSONP.callbacks || []
// 按照 id 放置 callback
JSONP.callbacks[JSONP.callbackId] = callback
const paramKeys = Object.keys(params)
const paramString = paramKeys
.map(key=> `${key}=${params[key]}`)
.join('&')
const script = document.createElement('script')
script.setAttribute('src', `${url}?${paramString}`)
document.body.appendChild(script)
// id 占用,自增
JSONP.callbackId++
}
JSONP({
url: 'http://s.weibo.com/ajax/jsonp/suggestion',
params: {
key: 'test',
},
callbackKey: '_cb',
callback(result) {
console.log(result.data)
}
})
JSONP({
url: 'http://s.weibo.com/ajax/jsonp/suggestion',
params: {
key: 'excited',
},
callbackKey: '_cb',
callback(result) {
console.log(result.data)
}
})
可以看到现在请求的都是 http://s.weibo.com/ajax/jsonp/suggestion?key=test&_cb=JSONP.callbacks[1] 这样的,然后得到的 js 也是 JSONP.callbacks[1]() ,这样就不会有冲突的问题,也不污染全局域。
URI编码
上面的代码仍然存在一个小问题,
JSONP({
url: 'http://s.weibo.com/ajax/jsonp/suggestion',
params: {
a: '545&b=3'
b: '5',
},
callbackKey: '_cb',
callback(result) {
console.log(result.data)
}
})
会导致 a 的内容直接被拼写进字符串,导致覆盖了 b 的值,而用户真的只是想让 a 的值为 trdgd&b=2 而已。解决方案也简单,进行 URI 编码即可, encodeURIComponent('trdgd&b=2') 的结果为 trdgd%26b%3D2 。即将上面参数处理的部分改为
const paramString = paramKeys
.map(key=> `${key}=${encodeURIComponent(params[key])}`)
.join('&')
这里值得一提的是,由于最终的 URL 不能包含 ASCII 码以外的字符,所以其实当使用中文或者特殊字符时其实会被自动编码。而 +,空格,/,?,%,#,&,= 等字符在 URL 中则会出现歧义,只有手动编码后才能让服务器端正确解析。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- php如何实现session,自己实现session,laravel如何实现session
- AOP如何实现及实现原理
- webpack 实现 HMR 及其实现原理
- Docker实现原理之 - OverlayFS实现原理
- 为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性?
- 自己实现集合框架(十):顺序栈的实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C算法(第二卷:图算法)(第3版)
塞德威克(Sedgewick Robert) / 周良忠 / 第1版 (2004年1月1日) / 2004-4 / 38.0
《C算法(第2卷)(图算法)(第3版)(中文版)》所讨论的图算法,都是实际中解决图问题的最重要的已知方法。《C算法(第2卷)(图算法)(第3版)(中文版)》的主要宗旨是让越来越多需要了解这些算法的人的能够掌握这些方法及基本原理。书中根据基本原理从基本住处开始循序渐进地讲解,然后再介绍一些经典方法,最后介绍仍在进行研究和发展的现代技术。精心挑选的实例、详尽的图示以及完整的实现代码与正文中的算法和应用......一起来看看 《C算法(第二卷:图算法)(第3版)》 这本书的介绍吧!