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
它的基本思想是,网页通过添加一个