CORS 问题:Next.js 应用程序
CORS issue: Next.js application
我正在尝试使用 Dokku (Heroku) 部署 Next.js 应用程序。该应用程序以前部署到 Vercel 时没有错误,但在 Dokku 上部署 CORS 失败。我在修复它方面取得了一些进展。
Next.js 服务器通过 API 网关与另一个永恒的 Python Django API 通信。
最初 POST 请求出现“不存在 'Access-Control-Allow-Origin' header”错误。我将 header 添加到 moduleExports
:
next.config.js
const moduleExports = {
async headers() {
return [
{
source: "/api/(.*)",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
{ 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" }
]
}
]
},
async redirects() {
return [
{
source: '/account',
destination: '/account/profile',
permanent: true,
},
]
},
};
此后我开始收到一个新错误,预检选项请求没有 return 200。我向我的处理程序添加了选项请求检查:
pages/api/sign-up.js
export default async function handler(req, res) {
if (req.method === 'OPTIONS') {
res.status(200).end();
}
const { email, password1, password2, first_name, last_name } = await req.body
const response = await fetch(REGISTRATION_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify( { email, password1, password2, first_name, last_name } ),
});
const data = await response.json()
res.status(200).json(data)
}
此时,有趣的是,请求确实到达了网关并被接受,并且确实在 Django API 中成功创建了新用户。但是 next.js 服务器和客户端之间的通信仍然显示 CORS 错误,并且页面没有更新以显示成功。 CORS 错误返回到第一个错误“请求的资源上不存在 'Access-Control-Allow-Origin' header”。当然不同的是,早先用户不是在Django端创建的。
我的问题当然是如何解决这个问题,因为我现在没有想法或尝试。
你的问题是:
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
// ...
]
您不能将通配符 (*
) 与凭据请求结合使用。如 the section entitled Credentialed requests and wildcards of the MDN Web Docs about CORS 中所述:
When responding to a credentialed request, the server must not specify the "*
" wildcard for the Access-Control-Allow-Origin
response-header value, but must instead specify an explicit origin; for example: Access-Control-Allow-Origin: https://example.com
.
因此,您应该明确指定允许的来源,而不是使用通配符:
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "https://yourfrontendorigin.com" },
// ...
]
我正在尝试使用 Dokku (Heroku) 部署 Next.js 应用程序。该应用程序以前部署到 Vercel 时没有错误,但在 Dokku 上部署 CORS 失败。我在修复它方面取得了一些进展。
Next.js 服务器通过 API 网关与另一个永恒的 Python Django API 通信。
最初 POST 请求出现“不存在 'Access-Control-Allow-Origin' header”错误。我将 header 添加到 moduleExports
:
next.config.js
const moduleExports = {
async headers() {
return [
{
source: "/api/(.*)",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
{ 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" }
]
}
]
},
async redirects() {
return [
{
source: '/account',
destination: '/account/profile',
permanent: true,
},
]
},
};
此后我开始收到一个新错误,预检选项请求没有 return 200。我向我的处理程序添加了选项请求检查:
pages/api/sign-up.js
export default async function handler(req, res) {
if (req.method === 'OPTIONS') {
res.status(200).end();
}
const { email, password1, password2, first_name, last_name } = await req.body
const response = await fetch(REGISTRATION_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify( { email, password1, password2, first_name, last_name } ),
});
const data = await response.json()
res.status(200).json(data)
}
此时,有趣的是,请求确实到达了网关并被接受,并且确实在 Django API 中成功创建了新用户。但是 next.js 服务器和客户端之间的通信仍然显示 CORS 错误,并且页面没有更新以显示成功。 CORS 错误返回到第一个错误“请求的资源上不存在 'Access-Control-Allow-Origin' header”。当然不同的是,早先用户不是在Django端创建的。
我的问题当然是如何解决这个问题,因为我现在没有想法或尝试。
你的问题是:
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
// ...
]
您不能将通配符 (*
) 与凭据请求结合使用。如 the section entitled Credentialed requests and wildcards of the MDN Web Docs about CORS 中所述:
When responding to a credentialed request, the server must not specify the "
*
" wildcard for theAccess-Control-Allow-Origin
response-header value, but must instead specify an explicit origin; for example:Access-Control-Allow-Origin: https://example.com
.
因此,您应该明确指定允许的来源,而不是使用通配符:
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "https://yourfrontendorigin.com" },
// ...
]