向 Next.js 13.4.4 端点发出 POST 请求时出现 CORS 错误

han*_*ren 7 cross-domain cors reactjs next.js next.js13

我使用的是 Next.js 版本 13.4.4,并且有一个端点 http://localhost:5000/logout。在我的src/app/logout/route.tsx文件中,我有以下代码:

import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest) {
  return new NextResponse("POST: /logout");
}
Run Code Online (Sandbox Code Playgroud)

现在,我尝试从 http://localhost:3000 上运行的另一个应用程序调用此端点。但是,我不断遇到以下错误:

Access to XMLHttpRequest at 'http://localhost:5000/logout' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Run Code Online (Sandbox Code Playgroud)

如何解决此 CORS 错误并成功向 Next.js 13.4.4 中的 http://localhost:5000/logout 端点发出 POST 请求?

 const response = await fetch('http://localhost:5000/logout', {
     method: 'POST',
     headers: {
          'Content-Type': 'application/json'
      },
      credentials: 'include',
  });
Run Code Online (Sandbox Code Playgroud)

我的解决方案:

我能够通过手动将选项添加到我的route.tsx并添加下面列出的标头来修复错误

export async function OPTIONS(request: NextRequest) {
    const origin = request.headers.get('origin')

    return new NextResponse(null, {
        status: 204,
        headers: {
            'Access-Control-Allow-Origin': origin || '*',
            'Access-Control-Allow-Methods': 'GET,OPTIONS,PATCH,DELETE,POST,PUT',
            'Access-Control-Allow-Headers': 'Content-Type, Authorization'
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

Ham*_*ywa 5

\xe2\x9a\xa0\xef\xb8\x8f 在 nextJS 13 中解决这个问题需要注意一些事情。

\n
    \n
  1. 导出处理程序文件OPTIONS中的函数route.ts,如下所示。
  2. \n
  3. 确保/在代码中发出提取请求时删除试用。
  4. \n
  5. 如下修改您的next.config.js文件以更新所有响应的标题。
  6. \n
\n

解决方案详细信息和代码

\n
    \n
  1. 为了修复它nextJs 13,您必须OPTIONS在路由处理程序中导出异步函数,如下app/api/route.ts文件所示。\n (您可以调整它以仅允许来自特定来源的请求,但\n这里我允许所有来源。)
  2. \n
\n
// app/api/route.ts\n\n  export async function OPTIONS(request: Request) {\n  const allowedOrigin = request.headers.get("origin");\n  const response = new NextResponse(null, {\n    status: 200,\n    headers: {\n      "Access-Control-Allow-Origin": allowedOrigin || "*",\n      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",\n      "Access-Control-Allow-Headers":\n        "Content-Type, Authorization, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version",\n      "Access-Control-Max-Age": "86400",\n    },\n  });\n\n  return response;\n}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • 确保仅包含您将支持的 HTTP 方法。OPTIONS 方法必须包含在允许的 HTTP 方法中,因为浏览器将使用它来确定是否实施 CORS 保护。在上面的代码中,我添加了除 PATCH 之外的所有 HTTP 方法。
  • \n
\n
    \n
  1. 确保在代码中向路由发出提取请求时不要添加尾部斜杠。例如https://my-next-js-app.com/api/与https://my-next-js-app.com/api不同。如果包含尾随/,服务器可能会发回 308 重定向,但由于某种原因,浏览器也会触发 CORS 错误!再次,在代码中发出提取请求时删除尾随的“/”。

    \n
  2. \n
  3. 修改next.config.js如下

    \n
  4. \n
\n
// next.config.js\nmodule.exports = {\n  async headers() {\n    return [\n      {\n        // matching all API routes\n        source: "/api/:path*",\n        headers: [\n          { key: "Access-Control-Allow-Credentials", value: "true" },\n          { key: "Access-Control-Allow-Origin", value: "*" },\n          {\n            key: "Access-Control-Allow-Methods",\n            value: "GET,OPTIONS,PATCH,DELETE,POST,PUT",\n          },\n          {\n            key: "Access-Control-Allow-Headers",\n            value:\n              "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",\n          },\n        ],\n      },\n    ];\n  },\n};\n\n
Run Code Online (Sandbox Code Playgroud)\n