jsonp 的介绍与使用

428 阅读1分钟

jsonp 介绍

jsonp 的作用是利用 <script> 标签没有跨域的限制,从而达到与第三方通讯的目的。

此时 <script> 标签的 src 属性是第三方的 API 地址,这样页面加载的时候,就会请求这个 API 。前后端约定好一个函数,这个函数名会以查询参数的形式传给后台,后台拿到这个函数后,会把数据传给这个函数,然后将这个带有数据的函数回传给前端。

由于 <script> 元素请求的脚本,会直接当作代码运行,这时,只要浏览器定义了这个函数,该函数会立即调用。

使用例子

创建一个文件夹 jsonp-demo,在这个文件夹中创建一个 templates 文件夹,并在 templates 创建index.html 文件,该 html 文件中的 <script> 标签会请求后台的 API ,代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>auto complete</title>
</head>

<body>
  年龄 <span id="age"></span>
</body>
<script>

  function getAge(data) {
    document.getElementById('age').innerHTML = data.age;
  }
</script>
<script src="http://127.0.0.1:3000/js?call=getAge"></script>

</html>

jsonp-demo 目录下创建 server.js ,定义 API 接口用于将数据传给前端,该文件的代码如下:

var http = require('http');
var url = require('url');

http.createServer(function (req, res) {

  // 解析 url 参数
  var path = req.url.split('?')[0];
  if (path === '/js') {
    res.writeHead(200, { 'Content-Type': 'text/javascript;charset=utf-8' });
    var params = url.parse(req.url, true).query;
    // 设置返回的内容
    res.end(`${params.call}({
      code: 200,
      age: 20,
      friends: [
        {
          age: 18,
          name: 'tom'
        },
        {
          age: 19,
          name: 'bob'
        }
      ]
    })`);
  } else {
    res.end('ok');
  }

}).listen(3000, function () {
  console.log("OK,访问:localhost:3000");
});

jsonp-demo 目录下创建 client.js ,用于返回 html 模板,该文件的代码如下:

var http = require("http");
var fs = require("fs");
var path = require("path");

// 创建服务器
http.createServer(function (request, response) {
  // 如果链接的路径是 /index 时,返回的页面的 index 页面
  if (request.url === '/index') {
    // 使用 path.join 拼接路径
    var filePath = path.join(__dirname, "templates", "index.html");
    fs.readFile(filePath, function (err, data) {
      // 如果出现错误就抛出 err,没出错就把 html 页面返回给浏览器
      if (err) {
        throw err;
      } else {
        response.end(data);
      }
    })
  } else {
    // 如果不调用 end 其他请求客户端将永远处于等待状态
    response.end()
  }
}).listen(3100, function () {
  console.log("OK,访问:localhost:3100");
});

然后分别用 node 执行 server.js 和 client.js ,之后用浏览器访问 http://127.0.0.1:3100/index,可以发现端口为 3100 的页面成功的访问了 3000 接口。

1.png

使用例子的完整代码可在这个仓库中查看

参考

  1. JSONP 的工作原理是什么?

  2. Node.js 服务器对应的路由返回对应的 HTML 文件

  3. 浏览器同源政策及其规避方法

  4. Node.js 创建第一个应用

  5. Node.js GET/POST请求