jsonp


1 使用Node.js创建http服务

### 查看node版本
C:\Users\Admin\WebstormProjects\html>node -v
v12.18.3
### 运行js文件
node xxx.js

2 谷歌游览器设置允许跨域

--args --disable-web-security  --user-data-dir=F:\chrome


3 ajax跨域演示

// 使用node运行当前js文件
// node http.js
const http = require('http');
http.createServer((request, response) => {
    response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    const weather = "北京 晴 18~32";
    response.write(weather);
    response.end();
}).listen(8080);
<!--
    http.html
-->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
    $.ajax({
        url: "http://localhost:8080/", success: function (result) {
            alert(result);
        }
    });
</script>


4  服务端将要发送的数据填充在一条js语句中

  • 服务端:将要发送的数据填充在一条js语句中
  • 客户端:<script src="服务端接口地址"  
// node http.js
const http = require('http');
http.createServer((request, response) => {
    response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    const weather = "北京 晴 18~32";
    //将要返回的实际数据,填充进一条合法的js语句中,进而返回一条js语句到客户端被script自动执行
    response.write(`alert("${weather}")`);// alert("北京 晴 18~32")
    response.end();
}).listen(8080);
<!--
    http.html
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp-02</title>
</head>
<script src="http://localhost:8080/"></script>
<body>
</body>
</html>

 

// http.js
const http = require('http');
http.createServer((request, response) => {
    response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    const weather = "北京 晴 18~32";
    response.write(`document.write("${weather}")`);// document.write("北京 晴 18~32")
    response.end();
}).listen(8080);
<!--
    http.html
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp-03</title>
</head>
<script src="http://localhost:8080/"></script>
<body>
</body>
</html>


5 服务端返回的是一个函数的调用

提前在客户端定义一个函数,用于处理服务端返回的请求,服务端仅使用函数名拼接一条函数调用的js语句

5.1  客户端script标签写死了

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

http.createServer((request, response) => {
    response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    const Url = url.parse(request.url, true);
    console.log(Url);
    //funName是我请求参数的key
    const funName = Url.query.funName;
    const weather = "北京 晴 18~32";
    response.write(`${funName}("${weather}")`);// funName("北京 晴 18~32") 直接调用这个函数
    response.end();
}).listen(8080);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp-04</title>
</head>

<script>
    function show(weather) {
        //怎么写由客户端决定
        //document.write(weather);
        //console.log(weather);
        alert(weather);
    }
    //
    //show("来自我自己的天气预报");
</script>
<!--!函数定义应该放在上面-->
<!--script是在页面写死了,只能在加载过程中执行一次-->
<script src="http://localhost:8080?funName=show">
    
</script>
<body>
</body>
</html>


5.2 动态创建script元素

每次单击按钮时动态创建 <script元素

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

http.createServer((request, response) => {
    response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    const Url = url.parse(request.url, true);
    //console.log(Url);
    //funName是我请求参数的key
    const funName = Url.query.funName;
    const weather = "北京 晴 18~32";
    response.write(`${funName}("${weather}")`);// funName("北京 晴 18~32") 直接调用这个函数
    response.end();
}).listen(8080);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp-03</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<button id="click">clickMe</button>
<script>
    $("#click").click(function () {
        // 不要用$("<script>")动态创建<script>元素
        // 浏览器会强行将<script>解析为标签
        const script = document.createElement("script");
        script.src = 'http://localhost:8080?funName=show';
        document.body.appendChild(script);
    });
    function show(weather) {
        alert(weather);
        //每次单击时都会创建<script>,反复单击会导致<script>堆积
        //删除添加的script元素
        $("body>script:last").remove();
    }
</script>

<body>
</body>
</html>

6 jQuery 中的jsonp

jQuery对 jsonp方式跨域进行了终极的简化

// 服务端的代码还是一样都不能少
const http = require('http');
const url = require('url');

http.createServer((request, response) => {
    response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    const Url = url.parse(request.url, true);
    // 只能是callback
    const callBack = Url.query.callback;
    const weather = "北京 晴 18~32";
    response.write(`${callBack}("${weather}")`);// funName("北京 晴 18~32") 直接调用这个函数
    setTimeout(function () {
        response.end();
    }, 1000);
}).listen(8080);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp-03</title>
</head>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<button id="click">天气预报</button>
<script>
    $("#click").click(function () {
        $.ajax({
            url: "http://localhost:8080",
            type: "get",
            // 其实也是动态创建<script>
            // 借助<script>发送跨域请求
            // 必须有服务器端的支持!
            // 打开游览器即可看到
            dataType: "jsonp",
            success: function (weather) {
                alert(weather);
            }
        });
    });
</script>

<body>
</body>
</html>

 

// SpringBoot项目
// http://localhost:5000/getAUth?callback=getAUth
@ResponseBody
@GetMapping("/getAUth")
public String getAUth(@RequestParam String callback) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();

    HashMap<String, String> auth = new HashMap<String, String>();
    auth.put("1", "添加用户");
    auth.put("2", "添加部门");
    // ...

    // 服务端需要特殊处理
    return callback + "(" + mapper.writeValueAsString(auth) + ")";
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp-05</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<button id="click">获取权限</button>
<script>
    let auth;
    $(document).ready(function () {
        $("#click").click(function () {
            $.ajax({
                url: "http://localhost:5000/getAUth",
                type: "get",
                dataType: "jsonp",
                success: function (data) {
                    auth = data;
                    console.log('auth => ', auth);
                }
            });
        });
    });
</script>
<body>
</body>
</html>

 


7 总结

jsonp 需要前后端配合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值