简单直白的解释 JSONP 的由来及实现原理
JSONP 详解,不信你听不懂
对于一样技术,先了解其发展的背景十分重要。因为了解了背景,才能明白他为何要如此设计,能解决什么问题。
原理有点枯燥,我就挑口语化的来说,你能听懂就行。对术语有兴趣的可以继续谷歌下去。
JavaScript 是一种在 Web 开发中经常使用的前端动态脚本技术。在 JavaScript 中,有一个很重要的安全性限制,被称为 Same-Origin Policy(同源策略)。
由于同源策略的限制,XmlHttpRequest (which 是 Ajax 实现的方式) 只允许请求当前源(域名、协议、端口)的资源。为了实现跨域请求,可以通过 script 标签实现跨域请求,然后在服务端输出 JSON 数据并执行回调函数,从而解决了跨域的数据请求。
利用在页面中创建<script>
节点的方法向不同域提交 HTTP 请求的方法称为 JSONP,这项技术可以解决跨域提交 Ajax 请求的问题。
也就是出现 JSONP 是为了在同源策略所保证的安全的前提下,绕个弯突破限制获取资源。
上文说到是利用在页面中创建 <script>
节点,修改 script 节点的 src 属性到目标地址来获取资源,这里就有了 script 标签的局限性 —— script 标签仅支持 GET 请求方式。
这就是 JSONP 只能是 GET 请求的前因后果。
JSONP 实现细节
使用 script 标签,改变 src 属性为目标地址,服务器返回的就是一个文本 (文本内是一个函数),这个函数作为 js 被执行。
伪代码
生成的 script:
// 这是一个由 JSONP 生成的 script 标签
// 他请求了一个 user 对象
// 注意这里的 *callback=JSONP_CB* 这里定义了一个回调函数的名称,通常在使用 jQ 的时候,可以自定义回调函数名或者不定义由 jQ 自动生成。
// 这个函数名将会被后端使用,包裹着数据传回。
<script src="http://localhost:1111/user/1?callback=JSONP_CB"></script>
后端代码:
// 返回 user 对象, 通常情况下我们只需要返回 json体
// 而 JSONP 则会使用回调函数名包裹着数据返回,这也就是一个 js 语法, 等于是调用了一次 JSONP_CB 函数。
return "JSONP_CB({'id': 1, 'name':'nickChen'})"
这里就是回调函数使用的关键了:
// 服务器返回的 JSONP_CB({'id': 1, 'name':'nickChen'}) 因为在 script 标签下,作为一个 js 代码运行了
// 然后就可以看到巧妙地利用了回调函数取回了数据并执行你的方法来处理数据、
// 将 JSONP_CB 注册到成为一个函数
window[callbackName] = function(data){
// 关键了,调用你的方法来处理数据
callback(data);
// 清场
window.document.body.removeChild(scriptElem);
};
后续测试
script, img, iframe, link 四个标签都可以请求到跨域资源,其中 link 也可以完成 script标签实现的 JSONP 功能,即可以调起回调函数。 img 不能处理文本内容,但是可以监听是否响应。iframe 就是把请求的资源当做 HTML渲染咯(即回调函数会作为文本显示)。
总结
至此,也看到了 JSONP 的实现方式,可以看到 JSONP 的设计还是十分巧妙地,而实现上又非常简单。
当然了,现在也可以不使用 JSONP 的方式来处理跨域了,可以使用 CORS
来解决跨域。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]