JSONP跨域解决方案底层原理

跨域(非同源策略请求)

  • 同源策略请求 ajax / fetch
    部署到服务器上
  • xampp 修改本地的host文件
    请求http://127.0.0.1:1234/index.html相当于请求http://api.qq.com/getData
    127.0.0.1:1234 http://api.qq.com/
    
  • 服务器拆分
    web服务器:静态服务 kbs.sports.qq.com
    data服务器:业务逻辑和数据分析 api.sports.qq.com
    图片服务器
  • 三者一样就是同源,只要有一个不同就是跨域
    协议
    域名
    端口号
  • 只有访问类型为xhr(XMLHttpRequest)的才会出现跨域

JSONP

  • 服务器可以响应js代码
    app.all('/jsonp-server', (request, response) =>{
        const data = {
            name: 'Nliver的学习笔记-1'
        };
        //将数据转化为字符串
        let str = JSON.stringify(data);
        //返回结果形式 是一个函数调用,而函数的实参就是我们想给客户端返回的结果数据
        response.end(`handle(${str})`);
    });
    
  • 客户端提供handle函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>原理演示</title>
        <style>
            #result {
                width: 300px;
                height: 100px;
                border: solid 1px #78a;
            }
        </style>
    </head>
    <body>
        <div id="result"></div>
        <script>
            //处理数据
            function handle(data) {
                //获取 result 元素
                const result = document.getElementById('result');
                result.innerHTML = data.name;
            }
        </script>
        <script src="http://127.0.0.1:8000/jsonp-server"></script>
    </body>
    </html>
    
在jQuery中使用JSONP
  • 客户端
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>jQuery-jsonp</title>
        <style>
            #result {
                width: 300px;
                height: 100px;
                border: solid 1px #089;
            }
        </style>
        <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    </head>
    <body>
        <button>点击发送 jsonp 请求</button>
        <div id="result">
    
        </div>
        <script>
            // 在callback中填写处理函数
            $('button').eq(0).click(function(){
                $.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function(data){
                    // console.log(data);
                    $('#result').html(`
                        名称: ${data.name}<br />
                        校区: ${data.city}
                    `)
                })
            });
        </script>
    </body>
    </html>
    
  • 服务器端
    //jQuery服务中的jsonp
    app.all('/jquery-jsonp-server', (request, response) =>{
        // response.send('console.log("hello jsonp")');
        const data = {
            name: 'Nliver',
            city: ['北京', '上海', '深圳']
        };
        //将数据转化为字符串
        let str = JSON.stringify(data);
        //接收 callback 参数
        let cb = request.query.callback;
    
        //返回结果
        response.end(`${cb}(${str})`);
    });
    

示例:

  • 后端实现
    const Koa = require("koa");
    const fs = require("fs");
    const app = new Koa();
    
    app.use(async (ctx, next) => {
      if (ctx.path === "/api/jsonp") {
        const { cb, msg } = ctx.query;
        ctx.body = `${cb}(${JSON.stringify({ msg })})`;
        return;
      }
    });
    
    app.listen(8080);
    
  • 普通js示例:
    <script type="text/javascript">
      window.jsonpCallback = function(res) {
        console.log(res);
      };
    </script>
    <script
      src="http://localhost:8080/api/jsonp?msg=hello&cb=jsonpCallback"
      type="text/javascript"
    ></script>
    
JQuery Ajax 示例:
  • 第一种;
    <script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js"></script>
    <script>
      $.ajax({
        url: "http://localhost:8080/api/jsonp",
        dataType: "jsonp",
        type: "get",
        // 传过去的数据
        data: {
          msg: "hello"
        },
        // 相当于上面的cb,对应的函数就是下面的success
        jsonp: "cb",
        success: function(data) {
          console.log(data);
        }
      });
    </script>
    
  • 第二种前端代码:
    $.ajax({
    	url: 'http://127.0.0.1:8001/list',
    	method: 'get',
    	dataType: 'jsonp',  // 执行的是JSONP请求
    	success: res => {
    		console.log(res);
    	}
    });
    
  • 后端代码:
    app.get('/list', (req, res) => {
    	let {
    		callback = Function.prototype // 如果不存在这个函数的话,默认值
    	} = req.query;
    	let data = {
    		code: 0,
    		messageL '哈哈'
    	};
    	res.send(`${callback}(${JSON.stringify(data})`);
    });
    
  • callback = ... 是jQuery帮我们创建多的一个全局函数,当返回的时候全局函数执行,会帮助我们把success执行
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值