JSONP和JSON是不一样的。JSON(JAVAScript Object Notation)是一种基于文本的数据交换方式,或者叫做数据描述格式。而JSONP(JSON with Padding)是一种方式或者说非强制性协议。它是为了解决某个难题而产生的一种技术方式。

为什么会用到JSONP呢?

我们平时在用ajax请求服务端数据时,一般是这么写的:

Copy$.ajax({ type: "get", url: "getData.php", dataType: "json", success: function (data, textStatus, jqXHR) { console.log(data); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert('fail'); }});

这是一段很普通的基于jQuery的AJAX请求,不会有什么问题。注意到:url里是getData.php,说明这个文件url是基于当前服务器的,例如可能是localhost,也就是前端发出的请求来源是localhost,后端肯定也是localhost。他们俩是在同一个域名下。当然,平时我们也不会特别注意。

这时候,假如这个url变成其它服务器上的地址,例如:'//www.lu-xu.com/d/uploads/2020-11/06/ksbyhfvg2oe.jpg 为什么使用jsonp?

出什么问题了?被限制请求了!

CopyXMLHttpRequest cannot load //www.lu-xu.com/d/uploads/2020-11/06/i4wtxjbh4gs.jpg No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://demo.52fhy.com' is therefore not allowed access.

也就是请求来源与服务器不是同一个域名,不允许访问。这就是浏览器同源策略:

Copy所谓"同源"指的是"三个相同":协议相同域名相同端口相同举例来说,http://www.example.com/dir/page.html这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下。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:不同源(端口不同)

同源政策规定,AJAX请求只能发给同源的网址,否则就报错。

那么,这时候该怎么办呢?我就是想通过js请求对方服务器上的资源!

除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制。

JSONPWebSocketCORS

本文只对JSONP作介绍。

如何使用JSONP

首先前端这边代码得改改,假设先不用jQuery:

Copy

后端服务器也要改改。

例如,在PHP语言中,后端服务器在API里返回JSON数据,一般是这么写的:

Copy$data = array('name' => '52fhy', 'age' => '22');echo json_encode($data);exit;

这里需要改成:

Copy$data = array('name' => '52fhy', 'age' => '22');handJsonp($data);//处理jsonpfunction handJsonp($data){ $callback = $_GET['callback'] ? : 'callback'; //默认使用callback echo sprintf("%s(%s)", $callback, json_encode($data)); exit;}

一旦请求成功,服务端输出了:

Copyhandler({name: "52fhy", age: "22"});

这时候浏览器就要响应了,找到handler()方法并执行,恰好,我们提前定义好了handler()方法。

这里为什么服务端没有限制访问呢?原因是我们通过动态添加了个:

Copy

它的基本思想是,网页通过添加一个