JSONP实现原理
JSON和JSONP
JSONP是JSON with padding(填充式JSON,参数式JSON)的缩写,这是一种突破浏览器同源策略进行跨域通信的实现方式。
和JSON相比,JSONP多出来的P就是padding(填充),因为服务器端响应的数据格式是这样的:
1 | callback({"name": "plusye"}); |
简单点理解,不就是JSON数据{“name”: “plusye”}填充在callback函数里吗?
JSONP实现
JSONP的实现是通过script标签,因为script中的src是不受浏览器同源策略影响的。
要实现JSONP,除了前端实现,后端也要处理JSONP的请求才行。这里我找个会处理JSONP请求的网站测试。在浏览器中输入:http://freegeoip.net/json/, 会得到下面的数据:
1 | {"ip":"2001:da8:214:1074:774:b28e:e896:4395","country_code":"CN","country_name":"China","region_code":"11","region_name":"Beijing","city":"Beijing","zip_code":"","time_zone":"Asia/Shanghai","latitude":39.9289,"longitude":116.3883,"metro_code":0} |
上面显示的是我的ip地理位置信息啥的。我们通过JSONP获取这个信息,并且在控制台输出:
1 | function getJson() { |
解释一下上面的代码:
1.动态创建一个script节点;
2.把请求的url给src;这里需要特别注意的是,url一般是:http://www.example.com?callback=callback这种格式的。要有一个参数和值,值是前端代码中的函数名。
3.把节点添加到head节点中。
当script节点添加到DOM中时,浏览器就会向服务器发送一个GET请求,请求url是http://freegeoip.net/json/?callback=getIP。服务器会获取callback的值getIp,然后把JSON数据当做getIp函数的实参,并返回给浏览器:
1 | getIP({"ip":"2001:da8:214:1074:774:b28e:e896:4395","country_code":"CN","country_name":"China","region_code":"11","region_name":"Beijing","city":"Beijing","zip_code":"","time_zone":"Asia/Shanghai","latitude":39.9289,"longitude":116.3883,"metro_code":0}); |
浏览器获得这个数据之后,会它当成JavaScript代码来解析,执行。就相当于调用getIP函数,传入的实参就是我要从服务器中获取的JSON数据,这样就跨域取得资源,在控制台输出。
JSONP的优缺点
优点:
1.JSONP简单易用,支持服务器和浏览器之间双向通信;
2.不受同源策略限制。
缺点:
1.从其他域加载代码执行,可能会有恶意代码,有风险;
2.只支持GET方法。