跨域
约 965 字大约 3 分钟
2025-03-15
跨域主要分为以下几种情况
- 跨域的 http 请求:
XMLHttpRequest
、Fetch API 、Ajax、Axios 等 - Web 字体(CSS 中通过
@font-face
使用跨源字体资源),因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。 - WebGL 贴图。
- 使用
drawImage()
将图片或视频画面绘制到 canvas。 - 来自图像的 CSS 图形。
1. 后端接口响应头添加 CORS 报文
简单来说 CORS 不需要前端人员配置,需要后端人员在接口响应头里加上以下 CROS 报文,浏览器拿到返回的报文后就不在检查了。
// 说明了支持跨域的来源
Access-Control-Allow-Origin: http://foo.example
// 说明了支持的跨域方法
Access-Control-Allow-Methods: POST, GET, OPTIONS
// 说明了 将接受的自定义header字段名
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
// 预检请求的结果能够被缓存多久,即在多久内可以省略 预检请求 。
Access-Control-Max-Age: 86400
2. JSONP
JSONP(JSON with Padding)是一种传统的跨域解决方案,通过动态创建<script>
标签来实现跨域请求,因为<script>
标签不受同源策略的限制。
需要前端人员封装一个回调函数,把回调函数名传递给后端,后端人员配合拿到相应数据后再把相应数据传递给前端,触发回调函数。 只能解决 get 请求的跨域,无法处理 delete、put、post 等请求。
<!DOCTYPE html>
<html>
<head>
<title>JSONP Demo</title>
</head>
<body>
<script>
function handleResponse(data) {
console.log("Received data:", data);
}
const script = document.createElement("script");
script.src = "http://example.com/api?callback=handleResponse";
document.body.appendChild(script);
</script>
</body>
</html>
// 假设是Node.js后端
const http = require("http");
http
.createServer((req, res) => {
const callbackName = req.url.match(/callback=([^&]+)/)[1];
const responseData = { message: "Hello, world!" };
res.writeHead(200, { "Content-Type": "application/javascript" });
res.end(`${callbackName}(${JSON.stringify(responseData)})`);
})
.listen(80, "example.com");
3. Proxy 代理
核心原理是在配置一个代理去转发你的请求,去和后端服务器通信。
因为浏览器和服务器之间有同源策略的限制,服务器和服务器之间没有。
1. nginx 在服务器端开启反向代理
用于生产环境,后端去配置,将前端服务部署的服务器地址配置到 nginx 上去,添加 CORS 信息
## 如果你要请求的真实的url为:http://api.example2.com/login
## 在代码里写 /api/login 即可
server {
listen 80;
server_name example1.com;
location /api {
# 定义代理目标
proxy_pass http://api.example2.com;
# 允许跨域请求
add_header Access-Control-Allow-Origin *;
# 允许带身份验证信息的跨域请求
add_header Access-Control-Allow-Credentials true;
# 允许的请求方法
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
# 允许的请求头
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
# 预检请求的有效期
add_header Access-Control-Max-Age 3600;
# 处理 OPTIONS 请求
if ($request_method = 'OPTIONS') {
add_header Content-Type 'text/plain; charset=utf-8';
add_header Content-Length 0;
return 204;
}
}
}
2. vue-cli
主要用于开发环境下,解决开发过程中本地环境连接服务器的问题。
1. devServer.proxy
所有请求转发到某个服务器的
module.exports = {
devServer: {
proxy: "http://localhost:4000", // 目标地址
},
};
2. http-proxy-middleware
多个 api 分别匹配多个服务器
module.exports = {
devServer: {
proxy: {
"/req1": {
target: "url1", // 请求变成 url1/req1
ws: true,
changeOrigin: true,
},
"/req2": {
target: "url2", // 请求变成 url2/req2
},
},
},
};
3. node.js
运行在网页应用部署所在的服务器上,负责把客户端的请求转发到真正的服务器上
1. CORS 中间件
const express = require("express");
const cors = require("cors");
const app = express();
// 使用 CORS 中间件,允许所有跨域请求
app.use(cors());
app.get("/api/data", (req, res) => {
res.json({ message: "这是来自 API 的数据" });
});
app.listen(3000, () => {
console.log("服务器运行在 http://localhost:3000");
});
2.http-proxy-middleware 中间件
自行在 node 服务器里引入该中间件,重写一遍代理的代码
更新日志
2025/8/24 08:17
查看所有更新日志
e7112
-1于