请实现一个jsonp

JSONP(JSON with Padding)是一种解决跨域问题的技巧,它利用了<script>标签不受同源策略限制的特性。不过,需要注意的是,JSONP只支持GET请求,并且存在安全风险,因为它允许执行远程服务器上的任意代码。因此,在使用JSONP时需要谨慎,并确保只从可信的源加载数据。

下面是一个简单的JSONP实现示例:

  1. 服务器端(假设使用Node.js和Express)

服务器端需要提供一个返回JSONP响应的API。以下是一个简单的Express服务器示例:

const express = require('express');
const app = express();
const port = 3000;

app.get('/api/data?:callback', (req, res) => {
  const callback = req.query.callback;
  const data = { name: 'John Doe', age: 30 };
  const jsonp = `${callback}(${JSON.stringify(data)})`;
  res.setHeader('Content-Type', 'application/javascript');
  res.send(jsonp);
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

在这个示例中,服务器监听/api/data路径,并接受一个名为callback的查询参数。服务器将返回一个JSONP响应,其中包含一个名为data的对象。JSONP响应的格式是${callback}(${JSON.stringify(data)}),其中callback是客户端提供的回调函数名。

  1. 客户端(前端JavaScript)

在客户端,你可以创建一个<script>标签来加载JSONP响应,并定义一个全局回调函数来处理响应数据。以下是一个简单的客户端示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>JSONP Example</title>
</head>
<body>
  <script>
    function handleData(data) {
      console.log('Received data:', data);
      // 在这里处理数据,例如更新DOM或执行其他操作
    }
    
    function fetchJsonp() {
      const script = document.createElement('script');
      script.src = 'http://localhost:3000/api/data?callback=handleData';
      document.head.appendChild(script);
      script.onload = () => {
        document.head.removeChild(script); // 清理脚本标签
      };
      script.onerror = (error) => {
        console.error('Error loading JSONP:', error);
        document.head.removeChild(script); // 清理脚本标签
      };
    }
    
    fetchJsonp(); // 调用函数以发起JSONP请求
  </script>
</body>
</html>

在这个示例中,handleData函数是全局定义的回调函数,用于处理从服务器接收到的数据。fetchJsonp函数创建一个新的<script>标签,并将其src属性设置为服务器的JSONP API URL。查询参数callback被设置为handleData,以便服务器知道应该使用哪个回调函数名来包装响应数据。一旦<script>标签被添加到文档中,它就会自动发起GET请求并加载JSONP响应。当响应加载完成时,handleData函数将被调用,并接收到从服务器发送的数据作为参数。

posted @ 2024-12-22 09:50  王铁柱6  阅读(49)  评论(0)    收藏  举报