CORS错误:在Next.js上进行POST请求时,GET请求和Postman请求正常工作。

huangapple go评论64阅读模式
英文:

CORS error with Nextjs on POST requests while GET requests and Postman requests work fine

问题

我正在尝试访问一个使用Nextjs编写的RESTful API。该API在Postmancurl中能够正常工作。然而,我只在POST请求时遇到以下错误:

从原始地址'http://localhost:5173'访问'http://localhost:3000/api/articles'的XMLHttpRequest已被CORS策略阻止:对预检请求的响应未通过访问控制检查:所请求的资源上没有'Access-Control-Allow-Origin'头。

GET请求按预期工作。

我已经在响应中设置了所有必要的CORS头部信息:

res.headers.append("content-type", "application/json")
res.headers.append("Access-Control-Allow-Origin", req.headers.get('origin'))
res.headers.append("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE")
res.headers.append("Access-Control-Allow-Headers", "Content-Type")

我已经多次检查过,所有的urls都是正确的(包括上面代码中的req.headers.get('origin'))。也许我漏掉了一些重要的东西?

首先,我尝试通过Postman访问API,一切都按预期工作。然后,我实现了GET请求,仍然没有问题。但我无法使POST请求工作。

设置

API是使用Nextjs 13.4.4编写的,客户端应用程序是使用react 18编写的。
我正在使用axios从客户端发出请求。

英文:

I am trying to access a RESTful API written in Nextjs. The API works well with Postman or curl. However, I get the following error on (only) POST requests:

Access to XMLHttpRequest at 'http://localhost:3000/api/articles' from origin 'http://localhost:5173' 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.

GET requests work as expected.

I have set all necessary CORS headers in the Response as:

res.headers.append("content-type", "application/json")
res.headers.append("Access-Control-Allow-Origin", req.headers.get('origin'))
res.headers.append("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE")
res.headers.append("Access-Control-Allow-Headers", "Content-Type")

I checked multiple times, and all urls are correct (including req.headers.get('origin') in the above snippet). Maybe I am missing something important here?

First I tried hitting the API via Postman and everything worked as intended. I then implemented GET requests and still no issue. But I cannot make POST requests work.

Setup

API is written in Nextjs 13.4.4, client application is written in react 18.
I am using axios to make requests from client.

答案1

得分: 1

Web browsers send a CORS preflight to the server to see if the CORS protocol is understood. Preflight only fetches whatever OPTIONS method returns. In my case, I had only defined POST and GET route handlers and just needed an OPTIONS handler that would send necessary CORS headers to the preflight. Here's an example:

export function OPTIONS(req: NextRequest): NextResponse<any> {
  const res = new NextResponse();

  if (isWhitelistOrigin(req)) {
    res.headers.append(
      "Access-Control-Allow-Origin",
      req.headers.get("origin")!
    );
  }
  res.headers.append("Content-Type", "application/json");
  res.headers.append("Allow", "GET,POST,OPTIONS");
  res.headers.append("Access-Control-Allow-Methods", "GET,OPTIONS,POST");
  res.headers.append(
    "Access-Control-Allow-Headers",
    "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Authorization, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"
  );

  return res;
}

isWhitelistOrigin is a helper function that returns true if I want to allow the request origin to access the API and false otherwise.

英文:

Ok so found a solution.

Web browsers send a CORS preflight to the server to see if the CORS protocol is understood.
Preflight only fetches whatever OPTIONS method returns. In my case, I had only defined POST and GET route handlers and just needed an OPTIONS handler that would send necessary CORS headers to the preflight. Here's an example:

export function OPTIONS(req: NextRequest): NextResponse&lt;any&gt; {
  const res = new NextResponse();

  if (isWhitelistOrigin(req)) {
    res.headers.append(
      &quot;Access-Control-Allow-Origin&quot;,
      req.headers.get(&quot;origin&quot;)!
    );
  }
  res.headers.append(&quot;Content-Type&quot;, &quot;application/json&quot;);
  res.headers.append(&quot;Allow&quot;, &quot;GET,POST,OPTIONS&quot;);
  res.headers.append(&quot;Access-Control-Allow-Methods&quot;, &quot;GET,OPTIONS,POST&quot;);
  res.headers.append(
    &quot;Access-Control-Allow-Headers&quot;,
    &quot;Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Authorization, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers&quot;
  );

  return res;
}

isWhitelistOrigin is a helper function that returns true if I want to allow the request origin to access the API and false otherwise.

huangapple
  • 本文由 发表于 2023年6月11日 21:40:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76450743.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定