聊聊 JSONP 的 P

网站建设知识 phpacg 2年前 (2018-04-24) 127次浏览 0个评论

JSONP 是 JSON With Padding 的缩写。一个典型的 JSONP 央求如下
<script src=”http://server.example.com/users/abc?callback=parseResponse”></script&gt;
前往值为
parseResponse({“name”: “Foo”, “id”: 1234, “rank”: 7});

其中 parseResponse 是由 callback 参数指定的,也就是 JSONP 中的 P(adding)。这个 P 可不复杂,第一个想到这么用的人,相对是个大牛。由于有了这个 P,处置了好些难题:
1. 回调效果。只需收回 script 央求,自动等候 callback 回调就好,并且精准得能秒杀 `onload` 等方案。
2. 跨域效果。由于阅读器的同源战略,跨域不时是前端的难题。跨域与平安毫不相关,JSONP 没有破坏平安性,同时却具有了片面跨域才干。巧妙而适用。
3. 协作效果。后端专注与数据处置与输入,前端专注与数据展现。除了 JSON 数据自身的格式商定,其他商定仅仅需求一个 P 就好。
好了,再说下去,估量很多人会不乐意了。JSONP 的优势也很清楚:
1. 无中间形状。不像 XHR(XMLHttpRequest) 那样,有丰厚的 status 、readyState 等属性,可以很精准地知道各种形状。
2. 只能 GET。不像 XHR 那样,可以全方位支持 GET、POST、PUT、DELETE。
3. 只能异步。XHR 是可以同步的,估量很多人没用过,同步其实是 XHR 的默许行为(省略 open 的第三个参数就代表同步)。
本文不聊其他的,专注聊聊那个P。
回到扫尾那个例子:
http://server.example.com/users/abc?callback=parseResponse
parseResponse 是一个全局函数。当页面上很多 JSONP 央求时,就有能够出现很多全局函数。虽然全局变量并不一定是恶魔,但不好好管理的全局变量真的有能够成为恶魔。管理的方案之一是给 P 引入命名空间:
http://server.example.com/users/abc?callback=JSONP.parseResponse
这样,一切 JSONP 的回调处置函数就都有了根,可以防止与其他函数的潜在抵触。
可是,这还得绞尽脑汁给 JSONP.xxx 命名,经常大家会想到一块,比如 xxx 经常会不约而同:
callback
handle
parseData
_Callback
jsonp

这种不约而同,虽然代表着英雄所见略同式的欣喜,但更多的是:我靠,你怎样也取这个名字?这可怎样处置呢?来试试 jQuery 类库。jQuery 的优秀相对不只仅是给你一个 $ 符号,jQuery 在很多方面思索得十分周到:
$.getJSON(“http://server.example.com/users/abc?callback=?&#8221;,
function(data) {
  console.log(data.name); // => Foo
});

很神奇的,只需求指定下 callback=? 就好,再也不用为命名犯愁了。原理是 jQuery 帮你随机命名了一个以后页面独一的全局 callback 函数,并且与 success 调用串接了起来。这样,就可以像运用 XHR 一样直接在回调中拿到 data 数据。jQuery 再好,也抵御不住 winter 等神人的不喜欢。这时,我们可以用各种 loader 来完成,比如:

seajs.use(“http://server.example.com/users/abc?callback=define&#8221;,
function(data) {
  console.log(data.name); // => Foo
});

经过 RequireJS、SeaJS、OzJS 等 XMD loader,我们也不再需求为回调函数名烦恼,只需给 callback 传入 define 就好。假设你有全站运用 loader 方案,更进一步,可以商定没有传 callback 参数时,默许就是 define. 这意味着关于静态 JSON 数据来说,可以静态化:

seajs.use(“http://server.example.com/users/abc.js&#8221;,
function(data) {
  console.log(data.name); // => Foo
});

这样,效劳端的 JSONP 数据直接可以是静态文件:

define({“name”: “Foo”, “id”: 1234, “rank”: 7});

这带来的益处看起来很小,实践上很有用。由于这意味着数据可以提早处置好,可以提早缓存,甚至可以静态化存储到 CDN 上,可以缓存到用户阅读器上。静态化的益处,谁用谁知道。用 define 固定住 callback 名,配合阅读器端的 loader,我们可以传输各种数据:
define([ … ]); // 数组格式,比如搜索提示数据
define(“….”); // 直接字符串,比如模板
这个方案,鄙人很无耻,还央求过一个专利,叫 JSONM 协议,M 是 Module(模块)。不过以上用法不在专利维护内容里,大家可以担忧大胆用。

P 还可以摇身一变,从 JSONP 变成 XHR,比如
http://server.example.com/users/abc?type=xhr
经过 type 参数,效劳端就会直接前往 JSON 数据,这样就可用在 XHR 调用中。Google 的 API 中有相似的设计,很灵敏。
JSONP 的这个 P,到此就谈完了。除了这个 P,更有应战的是 JSON 数据自身的设计。这外面学问大了去,等有时间再细说。

喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址