跳到主要内容

JSONP 跨域请求 JSON 数据

JSONP(JSON with Padding)是一种跨域获取 JSON 数据的非官方使用模式。它利用了某些 HTML 标签不受同源策略限制的特性,比如script标签可以引入不同源的 JavaScript 文件。

需要注意的是: JSONP 抓取的资源并不是直接的 JSON 数据,而是一个带有 JSON 数据作为参数的函数调用。

客户端期望返回的 JSON 格式

{ "name": "Jacky", "age": "18" }

JSONP 实际返回的格式

callback({ name: 'Jacky', age: '18' });

JSONP 利用了以下几种标签不受同源策略影响的特性:

  1. img标签的src属性可以引入不同源的图片资源
  2. link标签的href属性可以引入不同源的 CSS 文件
  3. iframe标签的src属性可以引入不同源的网页
  4. script标签的src属性可以引入不同源的 JavaScript 文件

浏览器如何解析 script 标签引入的资源

当使用script标签引入一个资源时,浏览器会将其作为 JavaScript 代码来执行。

例如有以下 HTML 代码:

<script src="./data.js"></script>
<script>
console.log(username);
</script>

假设data.js文件的内容如下:

var username = 'Jacky';

执行结果:

可以看到,script标签成功引入并执行了data.js中的代码,因此第二个script标签中可以访问到username变量。

使用 jQuery 发送 JSONP 请求

$.ajax({
type: 'get',
url: 'http://www.example.com/data',
dataType: 'jsonp',
jsonp: 'callback',
success: function (response) {
console.log(response);
},
});

其中的一些参数说明如下:

  • dataType: "jsonp"表示使用 JSONP 方式请求
  • jsonp: 'callback'指定回调函数名的参数名,默认为callback
  • 如果不指定jsonpCallback,返回的数据会传入success回调函数
  • 如果指定了jsonpCallback: 'handleResponse',则返回的数据会传入名为handleResponse的全局函数

跨域请求的完整示例

在下面的仓库中有一个使用 JSONP 跨域请求百度搜索建议数据的完整示例: https://github.com/sumingcheng/JavaScript-practise/tree/main/AJAX/baidu_search