JavaScript JSONP实现跨域

1. JSONP 是一种跨域问题解决方案,它利用了 script、img、iframe、link 等标签可以跨域的性质,来避免浏览器同源策略对跨域的限制. 不过除了 script ,其他标签均接收不到服务器数据.

2. JSONP 跨域步骤:

【1】JavaScript 实现对 URL 和 查询字符串 的拼接,并加上“callback=回调函数名”

【2】将拼接后的 URL 赋值给 script 标签的 src 属性

【3】定义全局函数 window[funcName] 用于动态回调

【4】script 忽略浏览器同源策略的限制,跨域请求目标资源,服务器收到访问请求后,获取查询字符串,并得到回调函数名

【5】服务器返回的是一段 JavaScript 语法文档,因此动态调用回调函数,若使用 express 框架,即为 res.send(`${callback}('${data}')`),此处 data 为一个变量名,存放着需要返回的数据

<script>
  function myJsonp(url, params, callback) {
    /* funcName 防止重名,随机生成 */
    let funcName = 'myJson_' + Math.random().toString().substr(2, 5);
    let arr = [];
    for (let key in params) {
      arr.push(`${key}=${params[key]}`)
    }
    arr.push(`callback=${funcName}`);
    // 创建 script 标签,并赋值 script.src
    const script = document.createElement('script');
    script.src = `${url}?${arr.join("&")}`;
    document.body.appendChild(script); // 在DOM中添加 script 标签,则后面会执行 script 请求服务器
    // 在 JavaScript 中定义全局函数
    window[funcName] = function (data) {
      callback(data);
      document.body.removeChild(script);
    }
  }
  // 使用myJsonp
  myJsonp("http://localhost:3000/index",
      {params: "我是coolFish"},
      (data) => {
        console.log(data + ' hello express');
      })
</script>

Express 部分:首先安装依赖 npm install express --save-dev,创建index.js文件,写入下面代码,运行 node index.js 

const express = require("express");
const app = express();
app.get("/index", (req, res) => {
  let { params, callback } = req.query; // 获取查询字符串
  console.log(params); // 我是coolFish
  console.log(callback); // funcName的值:【随机】myJson_05639
  /* res.send() 括号里的内容会被当做 JavaScript 语法解析 */
  res.send(`${callback}('${params}') 
    console.log('test res.send()');
  `);
});

app.listen(3000, () => {
  console.log("服务开启成功了"); //yellow
});

结果:

 

posted @ 2021-10-01 20:20  TwinkleG  Views(368)  Comments(1Edit  收藏  举报