JSON和JSONP是不同的;JSON是一种数据格式;JSONP是一种跨域交互数据的方法。
JSONP的全称是“JSON with Padding”。
JSONP是一种客户端与服务器之间进行跨域交互数据的方法。(狭义上,是用来交互JSON格式的数据;广义上,则不限于交互数据的格式。JSONP侧重的是这种跨域交互的方法。)
不是同一个域名就叫跨域,比如sand-box.cn页面中的JavaScript脚本,向zhuanfou.com的web服务器程序进行AJAX,那就是跨域,默认情况下是行不通的。
同一个域名下,不同的子域名之间也算跨域,d.zhuanfou.com和zhuanfou.com之间也算跨域的。
既然不能跨域AJAX,但可以使用JavaScript或jQuery在当前HTML文档里添加一个<script>标签来引入外部JS脚本,而这个JS脚本可以是由服务器程序动态生成的。
通过引入动态生成的JS脚本,就可以轻松地规避掉跨域问题,而实现客户端与服务器的数据交互。不过动态生成JS脚本的时候,返回时的头文件中要声明content-type属性为application/javascript
或application/x-javascript
或text/javascript
;否则浏览器未必知道这是一个JavaScript脚本文件。
首先,点击按钮,动态插入<script>标签:
function clickButton() { var s = document.createElement("script"); s.src = "https://zhuanfou.com/demo_jsonp"; document.body.appendChild(s); }
服务器端动态生成JS脚本(以python的tornado框架的template模板为例):
getResponse( {% raw data %} );
getResponse是JS中预设好处理返回结果的函数:
function getResponse(data) { var key, txt = ""; for (key in data) { txt += key + " --> " + data[key] + "<br>"; } document.getElementById("demo").innerHTML = txt; }
JSONP不仅仅可以跨域接受服务器返回的数据,还可以跨域传递数据信息给服务器。而实现的方式就是在引入JS脚本的URL中添加上参数和数据。如下所示:
function clickButton() { var s = document.createElement("script"); s.src = "https://zhuanfou.com/demo_jsonp?k1=v1&k2=v2&k3=v3"; document.body.appendChild(s); }
JSONP是一种处理跨域的方法思路,重在知道这种方法思路;至于是否传输的是JSON格式字符串,这不重要;而真正重要的是活学活用,万变不离其宗。