面试题-探索JSONP

3,249 阅读5分钟

有这样一个面试题: 什么是jsonp,jsonp为什么没有post。那么,我们先看看什么是jsonp,了解了在看这个问题。

什么是JSONP


JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器集成JavaScript返回至 客户端,通过javascript callback形式实现跨域访问。

为什么会有跨域这个说法呢?


因为同源策略!浏览器安全是来自于同源策略。什么是同源策略呢?我们知道在网络中安全非常重要,不然你的密码,账号,重要数据都会被别人窃取,别人可以在网上获取到这些数据,模仿成你,骗过浏览器,为所欲为,这样的情况是不允许发生的。于是就有了同源策略一说。 规定如下:

协议相同
域名相同
端口相同

满足以上要求的网页称为同源下的网页。

例如:
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同

不同源的网页共有三种行为会受到限制:

1. Cookie、LocalStorage、IndexDB无法读取。
2. DOM无法获得。
3. AJAX请求获取不到返回值。

这样一来,就很安全了!那么这么做有好处,为什么还需要跨域呢?因为不方便,因为同源策略一棒子打死了一片,有人用着不舒服,于是就有了jsonp跨域。说的这么高大上,可以说就是一个script小技巧。

说了这么铺垫知识,下面开始一段Long story简洁版 jsonp (多图预警!!!)

Long Story


小Po今天要做一个付钱的页面,页面显示账户余额,还要有一个付款的按钮。蹬蹬蹬。。搞定了:

然后他需要一个数据库,不然用户刷新一下,蹬蹬蹬。。又搞定了!

接下来给按钮加一个事件,加哪一个?我的DOM事件流有讲事件处理程序哟!,于是小Po愉快的加上了DOM2级事件处理程序,接下来向后端发一个请求吧!

  • 那就用form表单提交一个post这样没问题吧?蹬蹬蹬。。。。

成功的完成了,可是有个问题我必须的刷新一下才会显示,这样是不是体验很不顺畅。

那么还有什么可以发送请求的,a标签?不行,那个需要点击一下呢?而且a标签看起来很奇怪不是吗?那img标签怎么样?好像可行哦,试试,蹬蹬蹬。。。

  • 那就试试<img>来发送请求吧

不错,不错,我在<img>标签里面加了自动刷新,这样弹窗出来后不就可以自动刷新了吗?而且还有一个狗狗图片传过来,多有意思!简直太棒!

于是A同志高兴的提交了代码,没过多久,就被打回来了,你这个请求还不错,怎么老是给传个狗子过来,劳资不要狗,我要钱!你懂吗?钱!

于是,为了这个低俗的需求,小Po又得重新找,这回找到了<script>,这回别处岔子了。蹬蹬蹬。。。

  • 最后尝试下<script>,ORZ

于是小Po将img换成script,打出一个弹窗,嗯,有两个弹窗,一个是HTML的,一个是服务器中的,看会发生什么。

然后付款,怎么没扣钱???

虚惊一场~~~原来是没添加进body!!为啥?不为啥!记住吧。

竟然能在服务器端可以使用js,小Po仿佛发现了新大陆!,于是悄悄的在服务器返回的JS中操作了HTML,这样就能扣钱而不用刷新页面,一举两得,一石二鸟,一箭双雕。。。。完美!!!!

于是小Po自信的提交了代码,然而,并板凳还没坐热,意见又来了。

“小Po啊,你酱紫我后端很难做啊(点根烟),你看看,我还要知道你页面写的是啥,我才能写响应,这样我都可以做前端,要你何用?!(弹了烟头,踩灭)你在好好想想吧!还有哦,你这个<script>付一次钱就在页面添加一个script标签,真的麻烦。这么烂的代码,是要我带20米的砍刀么?(吐出烟雾,一脸gaygay)”。

小Po心惊胆颤的捡起键盘,颤巍巍的删除了response里面的代码,怀疑人生。算了,先ka掉重复script!再想解决办法。

搞定!小Po重拾信心,还有什么办法解决代码太过于耦合呢?既然我不能放在后端,那我放在页面里面怎么样,可是这个代码怎么执行呢?诶?放函数里面,让后端段响应的同时执行我页面的函数不就OK啦。

“喂,解决没?”

“大哥这样怎么样?”

“不行!代码还是太多了,爷没时间写你那个什么函数名字,你等会,我去找我的刀”

“(T T)ORZ”

  • 抓紧时间,再看看问题怎么解决

我带个参数过去,让后端能够截取函数名,响应的时候调用这个函数名对应的函数就好了,这样就不会让他知道我要执行什么代码。耦合不就降下来了吗?简直是一举。。。 =。= 先提交看看吧。

“来!头伸过来。。

已经提交上去了。”

“是吗?给你一次机会,嗯?!数据怎么传过去呢?”

“用json什么放在‘我要传输的数据’ 的那个位置就好了。”

“嗯。。。还行,过得去,今天就不砍你啦。给你个红包领着你的狗子回家吧。

“收工!”

jsonp为什么没有post


因为是动态创建script标签呀,script不能发post请求呀。完!