为什么jsonp只支持get请求?JSONP是同步还是异步

来源:互联网 发布:centos 7 minimal桌面 编辑:程序博客网 时间:2024/06/04 18:59

JSONP的原理

JSONP 是一种【请求一段 JS 脚本,把执行这段脚本的结果当做数据】的玩法。

所以,你能 POST 一段通过 script 标签引入的脚本吗?

(如果看过 JSONP 库的源码就知道,常见的实现代码其实就是 document.createElement(‘script’) 生成一个 script 标签,然后插 body 里而已。在这里根本没有设置请求格式的余地)。

所以JSONP的实现原理就是创建一个script标签, 再把需要请求的api地址放到src里. 这个请求只能用GET方法, 不可能是POST

JSONP的例子一

域名A中的JS代码AJAX请求域名为B的服务器数据,这就是跨域AJAX请求,默认情况下是不行的。

但是HTML中有地方可以跨域请求,比如img script标签,它们的src属性指向的地址可以是不在域名A下的(即跨域)。

那有人就利用了上面的特点,选择了script中src能够跨域获得内容的特性,研究出了JSONP这种hack协议。(src中请求都是GET)

那假设JSONP请求如下:

jsonp({    url: 'http://path/to/server/b',    params: {A: a, B: b},    success: function myCallback (response) {}})

背后其实在进行:

1.拼接一个script标签,,从而触发对指定地址的GET请求
2.那服务器端对这个GET请求进行处理,并返回字符串 “myCallback(‘response value’)”
3.那前端script加载完之后,其实就是在script中执行myCallback(‘response value’)
4.是不是就完成了跨域的请求,
5.是不是就是只能用GET

所以jsonp不会对服务器端代码或者内容做更改,因为它只能发送get请求

转自:https://segmentfault.com/q/1010000009708151

JSONP的例子二

一、JSONP

由于同源策略不会阻止动态脚本的插入到文档中去,所以催生出了一种很常用的跨域方式: JSONP(JSON with Padding)。

原理说起来也很简单:

假设,我们源页面是在a.com,想要获取b.com的数据,我们可以动态插入来源于b.com 的脚本:

script=document.createElement("script");  script.type="text/javascript";  script.src="http://www.b.com/getdata?callback=demo";  function demo(data) {    console.log(data.msg);  }  

这里,我们利用动态脚本的src属性,变相地发送了一个http://www.b.com/getdata?callback=demo的GET请求。这时候,b.com页面接受到这个请求时,如果没有JSONP,会正常返回json的数据结果,像这样:

{msg:"helloworld"}  

而利用JSONP,服务端会接受这个callback参数,然后用这个参数值包装要返回的数据:

demo({msg:"helloworld"});  

这时候,如果a.com的页面上正好有一个demo 的函数:

function demo(data) {    console.log(data.msg);  }  

当远程数据一返回的时候,随着动态脚本的执行,这个demo函数就会被执行。

到这里,你应该能明白这个技术为什么叫JSONP了吧?就是因为使用这种技术服务器会接受回调函数名作为请求参数,并将JSON数据填充进回调函数中去。

JSONP的优缺点

虽然JSONP在跨域ajax请求方面有很强的能力,但是它也有一些缺陷。

首先,它没有关于JSONP调用的错误处理,一旦回调函数调用失败,浏览器会以静默失败的方式处理。

其次,它只支持GET请求,这是由于该技术本身的特性所决定的。因此,对于一些需要对安全性有要求的跨域请求,JSONP的使用需要谨慎一点了。

由于JSONP对于老浏览器兼容性方面比较良好,因此,对于那些对IE8以下仍然需要支持的网站来说,仍然被广泛应用。不过,针对高级浏览器,建议还是使用接下来会介绍的CORS 方法。

JSONP是同步还是异步

首先搞清楚,在软件开发领域,在前端领域,同步和异步的概念分别是什么。

我在wikipedia上找到一个解释。其实可以简单的理解为:能立刻得到结果的,不影响代码顺序执行的,都是同步的。反之,都是异步的。

alert, confirm, prompt都需要较长时间执行,但它们并不影响代码顺序执行,所以,它们是同步的。

setTimeout, setInterval, ajax等网络请求方式,这些都是需要回调函数的,不能立刻得到结果,而且也不阻塞代码顺序执行,所以这些都是异步的。

再来看什么是jsonp:

jsonp可以理解为从网络加载的一段脚本,不是表达式,而是语句。通常的表现形式为,在请求的URL中传入一个要执行的函数的方法名,而在应答中调用这个方法。

所以,jsonp是异步的,并且是可以跨域请求的异步

JSONP异步的理解

ajax其实用它主要就是因为它的异步,它去服务器端取数据,html页面可以在它取数据期间接着走下面的,等ajax取回数据了再处理;

jsonp也是利用回调函数,去指定服务器上取数据的时候不用等待,等它取回来了直接用回调函数一处理,也达到了异步的效果呀

JSONP异步的例子

你可以试试写个内容如下的a.js

alert('a')

然后

var scn = document.createElement('script');scn.src = 'a.js';document.getElementsByTagName('head')[0].appendChild(scn);alert('b');

看看执行顺序是先a后b
还是先b后a
就知道是同步异步
你还可以在以上代码中加入async 来看看是否造成差异
执行结果是先b后a

参考:https://www.zhihu.com/question/35892596

原创粉丝点击