解决跨域——前后端协商jsonp

JSONP 原理

1.什么是 JSONP

JSONP(JavaScript with padding)是 JSON 的一种“使用方式”,可用于解决主流浏览器的跨域数据访问问题。

2.JSONP 原理

由于浏览器同源策略的限制,网页中无法通过 Ajax 请求非同源的接口数据。但是<script>标签不受浏览器同源策略的影响,所以可以通过 src 属性,请求非同源的 js 脚本。

因此,JSONP 的实现原理是,通过<script>标签的 src 属性,请求跨域的数据接口,并通过函数调用的形式,接收跨域接口响应回来的

数据

3.执行过程

1.客户端定义一个解析函数,如 jsonpCallback = function(res){}

2.通过 params 的形式(d)包装 script 标签的请求参数,并且声明执行函数(如 cbj=jsonpCallback)

3.后端获取到前端声明的执行函数(jsonpCallback),并以带上参数且调用执行函数的方式传递给前端

4.前端在 script 标签返回资源的时候就会去执行 jsonpCallback 并通过回调函数的方式拿到数据了。

4.缺点

由于 JSONP 是通过<script>标签的 src 属性+回调函数实现的跨域数据请求,所以 JSONP只支持 GET 数据请求,而不支持 POST 请求

JSONP 和 AJAX 区别

jsonp 和 Ajax 没有任何关系,因为 jsonp 没有用到 XMLHttpRequest 这个对象

jsonp 之所以能跨域,是因为他并不是发送 ajax 请求,并不是利用 XMLHTTPRequest 对象和服务端进行通信,他其实是利用动态创建的 script 标签,而 script 标签是没有同源策略限制的,可以跨域的

实现

前端 5500 端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>跨域的四种解决办法</title>
</head>
<body>
<script>
// 1.jsonp 原理是通过不受浏览器跨域限制的script标签的src属性跨域请求数据
// 缺点:只能发送GET请求,不安全并且难以维护
// 后端返回的是一个函数,但是这个函数是在前端定义的,把值注入到函数参数中
const jsonp = (name) => {
let script = document.createElement('script');
script.src = 'http://localhost:3000/api/jsonp?callback=' + name;
document.body.appendChild(script);
return new Promise((resolve) => {
window[name] = (data) => {
resolve(data);
};
});
};
jsonp(`callback${new Date().getTime()}`).then((res) => {
console.log(res);
});
</script>
</body>
</html>

后端 3000 端口

1
2
3
4
5
6
7
8
9
10
import express from 'express';
const app = express();
const port = 3000;
app.get('/api/jsonp', (req, res) => {
const { callback } = req.query;
res.send(`${callback}('jsonp data from backend')`);
});
app.listen(port, () => {
console.log('server is running');
});
1
2
pnpm init
pnpm i express @types/express @types/node

解决跨域——前后端协商jsonp
https://hugtyftg.github.io/2024/01/28/解决跨域——前后端协商jsonp/
作者
mmy@hugtyftg
发布于
2024年1月28日
许可协议