NodeJS CORS阻止的Next.js:没有HTTP ok状态

7lrncoxx  于 2022-11-29  发布在  Node.js
关注(0)|答案(2)|浏览(150)

我正在使用GraphQL在两个域客户端和服务器之间进行通信。我已经在我的API网站上启用了CORS,遵循vercel documentation,但它似乎抛出了一个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客户端?我没有使用Express。

slwdgvem

slwdgvem1#

我通过使用配置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**提供的灵感!

9jyewag0

9jyewag02#

最新的Next.js

x1月0n1x日
import { ApolloServer } from '@apollo/server';
import { startServerAndCreateNextHandler } from '@as-integrations/next';
import schema from '../../graphql';
import connectDatabase from '../../graphql/utils/mongoose';
import apiConfig from '../../graphql/utils/config';
import allowCors from '../../utils/cors';

const apolloServer = new ApolloServer({
  schema,
  introspection: true,
  playground: true,
  context: async () => {
    console.log('context ready');
    await connectDatabase(apiConfig.get('mongodb'));
    console.log('db connected');
  },
});

const handler = startServerAndCreateNextHandler(apolloServer, {
  context: async (req, res) => ({ req, res }),
});

export default allowCors(handler);
/实用程序/注解
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;
  }
  await fn(req, res);
};

export default allowCors;

相关问题