Skip to Content

面试导航 - 程序员面试题库大全 | 前端后端面试真题 | 面试

JSONP(JSON with Padding)是一种跨域请求数据的技术,它利用 <script> 标签不受同源策略限制的特性,解决了浏览器中的跨域请求问题。通常,浏览器的同源策略(Same-Origin Policy)会限制从一个源加载的网页与不同源的服务器进行交互,JSONP 就是通过动态创建 <script> 标签,绕过这个限制,达到跨域请求数据的目的。

JSONP 的工作原理

JSONP 的工作原理可以分为以下几个步骤;

  1. 请求方式:JSONP 通过 <script> 标签发起跨域请求,因为 <script> 标签不受同源策略的限制,可以从不同域加载资源。当客户端发送请求时,服务器返回的是一个 JavaScript 函数调用,而非普通的 JSON 数据。这样,客户端可以通过回调函数处理返回的数据,实现跨域访问。

  2. 如何发送请求:

    • 客户端通过在页面中动态创建一个 <script> 标签,发起请求。例如:
    const script = document.createElement('script'); script.src = 'https://moment.com/data?callback=myCallbackFunction'; document.body.appendChild(script);
    • 在这个请求的 URL 中,callback 参数指定了一个回调函数的名称。这个回调函数的内容将会在服务器响应后执行。
  3. 服务端响应:

    • 服务器端收到请求后,会返回一个包含回调函数调用的 JavaScript 代码。这段代码通常看起来像这样:

      myCallbackFunction({ name: 'moment', age: 18, });
  4. 客户端处理响应:客户端在页面中定义了一个回调函数 myCallbackFunction,当服务器响应到达时,这个回调函数会被调用,并且包含服务器返回的数据:

    function myCallbackFunction(data) { console.log(data); // { name: 'moment', age: 18 } }

JSONP 通过绕过浏览器的同源策略,解决了跨域问题,允许从不同域请求数据。其实现方式简单,客户端和服务器端只需做少量修改即可完成跨域请求。

它的缺点非常明显:

  1. 只支持 GET 请求:由于 JSONP 使用的是 <script> 标签,因此只支持 GET 请求,而不支持 POST 请求。这使得它不适用于所有的 API 请求,尤其是需要发送大量数据的请求。

  2. 安全性问题:JSONP 是通过执行返回的 JavaScript 代码来获取数据的,这可能会导致 XSS(跨站脚本攻击)等安全问题。如果返回的数据包含恶意脚本,可能会对客户端造成危害。

  3. 无错误处理机制:由于 JSONP 是通过动态脚本标签加载数据的,它没有内建的错误处理机制。一旦请求失败,可能无法很好地捕获错误。

可以通过使用 <iframe> 和 postMessage 进行跨域通信。这种方法适合于需要双向通信的场景,但是实现起来比 JSONP 要复杂一些。

代码示例

接下来我们编写一下客户端代码:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>JSONP Example</h1> <button onclick="requestData()">Get Data</button> <p id="result"></p> <script> function requestData() { const script = document.createElement('script'); script.src = 'http://localhost:3000/data?callback=handleResponse'; document.body.appendChild(script); } function handleResponse(data) { document.getElementById('result').innerText = `Name: ${data.name}, Age: ${data.age}`; } </script> </body> </html>

首先,你需要在项目中安装 express。你可以使用以下命令安装它:

npm init -y npm install express

然后再编写服务端代码:

const express = require('express'); const app = express(); const port = 3000; app.get('/data', (req, res) => { const data = { name: 'moment', age: 18, }; const callback = req.query.callback; res.send(`${callback}(${JSON.stringify(data)})`); }); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); });

在上面的代码中,客户端通过点击按钮触发 requestData() 函数,这个函数会动态创建一个 <script> 标签,src 属性设置为服务器的 URL,并将 callback=handleResponse 作为查询参数传递给服务器。当服务器返回时,回调函数 handleResponse 会被调用,返回的数据作为参数传入

服务器接受请求,获取 callback 参数,并返回一个包装在 callback 函数中的数据。客户端收到响应后,会执行该回调函数并将数据传递给它。

总结

JSONP 是一种通过动态生成 <script> 标签绕过浏览器同源策略,实现跨域请求数据的技术。它的优势在于简单易用,但存在只支持 GET 请求、存在安全隐患等局限性。对于现代的应用,CORS 和其他技术(如 WebSocket)已经逐渐取代了 JSONP,成为更为安全和高效的跨域方案。

最后更新于:
Copyright © 2025Moment版权所有粤ICP备2025376666