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" },
  // ...
]