【问题标题】:Next JS Blocked by CORS: Does not have HTTP ok status下一个 JS 被 CORS 阻止:没有 HTTP ok 状态
【发布时间】:2021-08-11 05:08:33
【问题描述】:

我正在使用 GraphQL 在两个域客户端和服务器之间进行通信。在vercel documentation 之后,我在我的API 网站上启用了CORS,但它似乎抛出了blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status. 错误。我在 GraphQL 中有这段代码:

function createApolloClient() {
  return new ApolloClient({
    ssrMode: typeof window === "undefined",
    link: new HttpLink({
      uri: <link>,
      credentials: "include",
      fetchOptions: {
        mode: "cors",
      },
    }),
  }),
 ...
}

在 API 网站中,next.config.js 文件有这样的内容:

module.exports = {
  async headers() {
    return [
      {
        // matching all API routes
        source: "/api/:path*",
        headers: [
          { key: "Access-Control-Allow-Credentials", value: "true" },
          {
            key: "Access-Control-Allow-Origin",
            value: <link>,
          },
          {
            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, Access-Control-Allow-Origin",
          },
        ],
      },
    ];
  },
};

我配置next.config.js 文件的方式有问题吗?还是问题出在 Apollo Client 中?我不使用 Express。

【问题讨论】:

  • next.config.js 代码显然不足以处理 OPTIONS 请求。 vercel.com/support/articles/… 的 Vercel 文档的 在单个 Node.js 无服务器函数中启用 CORS 部分显示了如果您以这种方式进行设置,需要如何对 OPTIONS 请求进行特殊处理。因此,如果您改为执行 在 Next.js 应用程序中启用 CORS,似乎可能需要包含类似的内容。

标签: node.js cors next.js apollo apollo-client


【解决方案1】:

我通过使用配置 CORS 的其他选项解决了这个问题:

const allowCors = fn => async (req, res) => {
  res.setHeader('Access-Control-Allow-Credentials', true)
  res.setHeader('Access-Control-Allow-Origin', '*')
  // another common pattern
  // res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
  res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS,PATCH,DELETE,POST,PUT')
  res.setHeader(
    'Access-Control-Allow-Headers',
    'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
  )
  if (req.method === 'OPTIONS') {
    res.status(200).end()
    return
  }
  return await fn(req, res)
}

我认为这段代码肯定会起作用,因为req.method === OPTIONS 部分的条件是请求所缺少的,即 HTTP ok 状态。我没有传递标头,而是使用了我在 API 上使用的 apolloServer 处理程序:

const apolloServer = new ApolloServer({
  schema,
  context: dbConnect(),
});

export const config = {
  api: {
    bodyParser: false,
  },
};

const handler = apolloServer.createHandler({ path: "/api/graphql" }); // THIS

传入并导出export default allowCors(handler)

感谢 @slideshowbarker 的启发!

【讨论】:

    猜你喜欢
    • 2021-04-26
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 2021-08-06
    • 2021-07-03
    • 2019-08-09
    • 2020-07-30
    • 2020-01-29
    相关资源
    最近更新 更多