vercel部署跨域问题
Published in:2024-04-12 | category: 前端 工程化

next.js 本地开发环境跨域

利用rewrites重写代理

next.config.js中:

1
2
3
4
5
6
7
8
9
async rewrites() {
return [
//接口请求 前缀带上/admin-api/
{
source: "/admin-api/:path*",
destination: `${process.env.NEXT_PUBLIC_NEXT_BASE_URL}/admin-api/:path*`,
},
];
},

利用headers配置返回头

next.config.js中:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
const CORS_HEADERS = [
{
key: "Access-Control-Allow-Credentials",
value: "true",
},
{
key: "Access-Control-Allow-Origin",
value: "*",
},
{
key: "Access-Control-Allow-Methods",
value: "GET,DELETE,PATCH,POST,PUT",
},
{
key: "Access-Control-Allow-Headers",
value: "Content-Type, Authorization",
},
];

async headers() {
// 跨域配置
return [
{
source: "/favicon.ico",
headers: [
{
key: "Cache-Control",
value: "public, max-age=86400",
},
],
},
{
source: "/admin-api/:path*", // 为访问 /admin-api/** 的请求添加 CORS HTTP Headers
headers: CORS_HEADERS,
},
{
source: "/specific", // 为特定路径的请求添加 CORS HTTP Headers,
headers: CORS_HEADERS,
},
];
},

利用middleware.js中间件进行跨域设置

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
// middleware.js

import { NextResponse } from "next/server";

export const config = {
// matcher: '/:lng*'
matcher: [
"/((?!api|admin-api|_next/static|_next/image|assets|favicon.ico|sw.js).*)",
],
};

export function middleware(req) {
const response = NextResponse.next();

// 设置 CORS 策略
response.headers.set("Access-Control-Allow-Origin", "*");
response.headers.set(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS"
);
response.headers.set(
"Access-Control-Allow-Headers",
"Content-Type, Authorization"
);

return response;
}

在服务器环境中跨域,例如 vercel

新建vercel.json的配置文件

利用route路由配置

next.config.js中:
"src": "/admin-api/*"表示访问/admin-api开头的页面应用下面的规则

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"routes": [
{
"src": "/admin-api/*",
"methods": ["GET", "POST", "PUT", "DELETE"],
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE",
"Access-Control-Allow-Headers": "Content-Type, Authorization"
}
}
]
}

利用rewrites配置重写请求路径

配置next.config.js

访问/admin-api/的请求会去执行根目录下api文件夹中的proxy.js

1
2
3
4
5
6
7
8
9
{
"rewrites": [
{
"source": "/admin-api/(.*)",
"destination": "/api/proxy"
}
]
}

api文件夹下创建proxy.js文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 该服务为 vercel serve跨域处理
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = (req, res) => {
let target = "";
// 代理目标地址
// xxxxx 替换为你跨域请求的服务器 如: http://baidu.com
if (req.url.startsWith("/admin-api")) {
//这里使用/admin-api serverless 的 admin-api 路径冲突,根据接口进行调整
target = "http://222.71.83.59:48080"; //这里就是在vite中配置的一样
}
// 创建代理对象并转发请求
createProxyMiddleware({
target,
changeOrigin: true,
pathRewrite: {
// 通过路径重写,去除请求路径中的 `/admin-api`
"^/admin-api/": "/",
},
})(req, res);
};

[vercel](https://vercel.com/)控制台中查看proxy.js的执行情况

image.png

注意:
根据 next.js官方文档vercel.json文件中不能同时配置rewritesheaders以及routes,否则会导致 Git 自动部署失败的问题

Prev:
构建工具对比与模块化规范
Next:
Rollup 打包原理与插件