我正在尝试创建一个应用程序,使用supabase作为数据库,vercel后端(url:http://localhost:3000/api/)和netlify前端(url:http://localhost:5173)。前端是一个带有 vite 的 React 应用程序,后端是带有express的无服务器功能列表。
问题是当我尝试从前端发出请求时,我收到 500 错误CORS 预检未成功。当我根据 documentation 将 CORS 标头添加到 vercel 时,就会发生这种情况。
我还尝试使用 npm 中的 cors 中间件并以 express way 添加标头,但由于某种原因,标头未发送(我似乎也无法以这种方式更改任何标头)。
任何帮助将不胜感激。
vercel.json:
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Credentials", "value": "true" },
{ "key": "Access-Control-Allow-Origin", "value": "http://localhost:5173" },
{ "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
{ "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
]
}
]
}
这是创建应用程序函数,我用它来初始化所有函数,因此我不会为所有函数编写相同的参数。
import express, { NextFunction, Request, Response, json } from "express"
import helmet from "helmet"
import cors from "cors"
import cookieParser from "cookie-parser"
export function createApp() {
const app = express()
app.use(customCorsMiddleware)
app.use(cookieParser())
app.use(helmet())
app.use(json())
const url = process.env.CORS_URL
const middle = cors({ origin: true, credentials: true,})
app.use(middle)
return app
}
看着“如何在 Vercel 上启用 CORS?”,我对“[如何启用 CORS 在 Vercel 上不起作用?]”(如何启用 CORS 在 Vercel 上不起作用?)很感兴趣,其中说:
结果 Vercel 会覆盖您放在 json 之外任何位置的 cors 设置。不可能在同一文件中混合标头数组和路由数组。但您可以在路由中添加标头。
这表明,如果您使用
routes
数组在 vercel.json
中定义路由,那么您应该将 CORS 标头放置在那里,而不是放在同一文件中单独的 headers
数组中。这样做可以确保 Vercel 不会覆盖您的 CORS 设置。
在
vercel.json
的上下文中,这意味着您应该将与 CORS 相关的标头移至 routes
定义内。
所以不要像这样定义标题:
{
"headers": [
// your CORS headers here
]
}
您可以将它们包含在
routes
数组中:
{
"version": 2,
"builds": [
{
"src": "./index.js",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/api/(.*)",
"dest": "./index.js",
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
"headers": {
"Access-Control-Allow-Origin": "http://localhost:5173",
"Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,PATCH,OPTIONS",
"Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
"Access-Control-Allow-Credentials": "true"
}
}
]
}
通过执行此操作,您将遵守 Vercel 对 CORS 设置的特定要求,这应防止与 Express 中间件设置发生任何覆盖或冲突。
如果 Vercel 的
vercel.json
CORS 配置在部署时有效地管理应用程序的 CORS,则在 Express 中间件中再次应用 CORS 设置可能是多余的。在这种情况下,仅在本地开发期间有条件地应用 CORS 中间件是有意义的。
对于本地测试,当您在本地运行服务器进行测试时,在中间件中设置 CORS 将非常有用,特别是当您的前端也在不同端口上本地运行时。
在 Express 中使用 CORS 中间件的条件逻辑可以使您的代码更加灵活并且能够适应不同的环境(本地与生产)。
您可以有条件地应用它进行开发:
if (process.env.NODE_ENV === 'development') {
const middle = cors({ origin: true, credentials: true });
app.use(middle);
}
如果 Vercel 的 CORS 设置满足您的所有要求,那么您在部署时可能不需要在 Express 设置中包含 CORS 中间件。有条件地应用到本地开发,可以确保您在不影响生产环境的情况下拥有一致的开发体验。