前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >json & jsonp

json & jsonp

作者头像
仇诺伊
发布2018-09-12 14:44:53
1.3K0
发布2018-09-12 14:44:53
举报
文章被收录于专栏:佳爷的后花媛佳爷的后花媛

image

对于JSON和JSONP,应该都不陌生,咳咳,不过最初对JSONP有点误解,以为是JSON的另外一个别名,其实二者风马牛不相及。

谈到Json和jsonp就不可避免要提到跨域这个话题了,以前对跨域的理解都是比较模糊的,还以为域名不同就是跨域了,那太狭隘了。非同源请求,均为跨域。

不过为什么会出现跨域?出于浏览器的同源策略限制,浏览器会拒绝跨域请求。

严格的说,浏览器并不是拒绝所有的跨域请求,实际上拒绝的是跨域的读操作。浏览器的同源限制策略是这样执行的:

  • 通常浏览器允许进行跨域写操作(Cross-origin writes),如链接,重定向;
  • 通常浏览器允许跨域资源嵌入(Cross-origin embedding),如 img、script 标签(主要是有src);
  • 通常浏览器不允许跨域读操作(Cross-origin reads)。*

等等,上面咋又来了个同源策略,本是同根生,相煎何太急啊。

大家互相开开心心的走亲访友多好。哼,谁知道你是我亲戚还是坏人,万一你来我家是想偷小鱼干的呢?还开开心心,本喵不得哭死啊。 同源策略 (Same-Origin Policy) 最早由 Netscape 公司提出, 所谓同源就是要求, 域名, 协议, 端口相同. 非同源的脚本不能访问或者操作其他域的页面对象(如DOM等). 作为著名的安全策略, 虽然它只是一个规范, 并不强制要求, 但现在所有支持 javaScript 的浏览器都会使用这个策略. 以至于该策略成为浏览器最核心最基本的安全功能, 如果缺少了同源策略, web的安全将无从谈起.(这段文字是cv的)

这下好了,同源策略下的web世界, 域的壁垒高筑, 保证各个网页相互独立, 互相之间不能直接访问, iframe, ajax 均受其限制, 而script标签不受此限制.

注: 如非特别说明, 均指非CORS的, 普通跨域请求.

咳咳,我们讲json呢,扯远了,快回来

哎,哎,相公,别敲我脑袋瓜子啊,疼,敲笨了你就只能有个笨媳妇。人家这不是麻溜的回来了嘛,你倒是给我说说json和惊悚有啥不同。

“你知道啥是json么?”

“本大喵当然知道,json是一种数据格式”

“手写一段给本汪瞅瞅”

代码语言:javascript
复制
// 描述一个人

var person = {
    "Name": "大宝",
    "Age": 1,
    "Company": "IBM",
    "Engineer": true
}

“算你上次没逃课,那你给我说说,这个json有啥要注意的地方?”

“咦,json不就简单的数据格式吗,有啥要注意?”

“就知道你上次没认真听,肯定开小差了,今晚回去小鱼干没了。”

“喵呜~~~人家错了,你再说一遍吧?嘤嘤嘤”

“记得下次考你,看仔细了”

image

image

image

image

image

image

image

image

■ ■■■■

这会儿带你认识认识jsonp了,看会儿惊悚片

“喵喵,你知道ajax么?”

“听过,但是不太了解”

“推荐一个blog,你去看看,下次讲给我听听,答的好有小鱼干吃哟”

“猴!得令”

image

代码语言:javascript
复制
    Ajax直接请求普通文件存在跨域无权限访问的问题,无论是静态页面还是动态页面,web服务,WCF(喵呜,这是啥?),但是在web页面上调用js文件时不受到跨域的影响(凡是拥有src属性的都有跨域的神奇能力),所以可以通过在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理,而处理这些数据的格式可以是json,而且json还被原生js支持,很完美了。

    方案如下: 

    Web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件,客户端在对json文件成功调用之后,获得了自己所需的数据,这就是jsonp,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住json数据,这样客户端就可以随意定制函数来自动处理返回数据。

    具体实现示例: 

    喵喵:远程服务器。cat.com 

    汪汪:本地服务器.dag.com 

1 miaomiao.js是cat.com根目录下的一个js文件。 代码如下

代码语言:javascript
复制
<pre style="margin: 0.5em 0px; padding: 0.4em 0.6em; border-radius: 8px; background: rgb(248, 248, 248); box-sizing: border-box;">alert(‘喵呜,我是喵喵’);</pre>

Jsonp.html是dag.com下的一个页面:

image

这里会弹出弹窗,现实跨域成功。

2 在jsonp.html页面定义一个函数。然后在远程文件miaomiao.js中传入数据进行调用。

image

miaomiao.js:

代码语言:javascript
复制
localHandler({"result":"我是远程猫js带来的数据"});

运行之后,显示本地调用成功,并且获取数据。但是如何让miaomiao知道它调用的dog函数叫什么呢?毕竟附近的dog太多了。

3 喵喵和汪汪想了一个办法,如果汪汪想要调用喵喵,就在返回的骨头上加一个标志,说我想调用XXX函数的js代码,你丫别给我传错了啊。于是喵喵就按照骨头上的需求来生成js脚本并且给汪汪一个响应“拿好你的骨头,别搞丢了” 汪汪的jsonp.html

image

上面实现的是编码动态查询,也是jsonp客户端实现的核心。

下面是如何完成jsonp调用的全过程。 上面url中的code参数表示dog告诉cat我要查询附近猪骨的信息,并且把一个叫callback的骨头给cat,说这是我们的暗号(boneHandler),别和其他狗子搞混了,你把结果都放到这块骨头的这个暗号中给我传过来。

代码语言:javascript
复制
    于是这个叫做boneResult.aspx的页面生成了一段这样的代码提供给jsonp.html
代码语言:javascript
复制
boneHandler({
    "code": "pig",
    "price": 170,
    "nums": 5
});

4 如何用jquery实现? Attention:jquery在处理jsonp类型的ajax时(虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮你生成回调函数并把数据取出来供success属性方法来调用

image

1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext(?)等框架都把jsonp作为ajax的一种形式进行了封装;

2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。

3、其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。

4、还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。

总而言之,jsonp不是ajax的一个特例,哪怕jquery等巨头把jsonp封装进了ajax,也不能改变着一点!

“傻喵,听懂了么?”

image

参考资料:

路易斯的blog(推荐看看他的blog,内容满赞的,尤其那个关于mac上使用alfred的技巧,很清晰)

阮一峰的日志

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1eteae3c4sdc0

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.08.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档