next.js 阿波罗-服务器-微:响应缺少标头“access-control-allow-methods:POST'

rqcrx0a6  于 2022-11-05  发布在  其他
关注(0)|答案(5)|浏览(188)

在我的next.js应用程序中,我尝试配置Apollo端点:

import { ApolloServer, gql } from "apollo-server-micro";

// This data will be returned by our test endpoint. Not sure if I need id? https://apuyou.io/blog/serverless-graphql-apollo-server-nextjs
const tacos = {
  meat: [
    {
      type: 'Al Pastor',
      imgURL: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/190130-tacos-al-pastor-horizontal-1-1549571422.png?crop=0.668xw:1.00xh;0.175xw,0&resize=480:*'
    },
    {
      type: 'Barbacoa',
      imgURL: 'https://i2.wp.com/www.downshiftology.com/wp-content/uploads/2021/02/Barbacoa-Tacos-3.jpg'
    },
    {
      type: 'Chorizo',
      imgURL: 'https://www.seriouseats.com/thmb/-8LIIIObcZMUBy-9gXlMsHcaeMI=/610x458/filters:fill(auto,1)/__opt__aboutcom__coeus__resources__content_migration__serious_eats__seriouseats.com__recipes__images__2014__04__20140428-sloppy-joe-chorizo-taco-recipe-food-lab-lite-8-503212a07b0a4d499952ff40aed57694.jpg'
    },
  ],
  fish: [
    {
      type: 'Camaron',
      imgURL: 'https://juegoscocinarpasteleria.org/wp-content/uploads/2019/07/1563435179_315_Tacos-De-Camarones-Con-Crema-De-Cal-Y-Cilantro.jpg'
    },
    {
      type: 'Salmon',
      imgURL: 'https://www.cookingclassy.com/wp-content/uploads/2015/04/salmon-tacos-with-avocado-salsa4-srgb..jpg'
    },
    {
      type: 'Pulpo',
      imgURL: 'https://images.squarespace-cdn.com/content/v1/5710a8b3e707ebb8c58fea2c/1590075315244-QNXQE1LGPH06HV3EDF6B/tacos_34.jpg?format=1000w'
    },
  ],
  veggi: [
    {
      type: 'Cauliflower',
      imgURL: 'https://minimalistbaker.com/wp-content/uploads/2017/07/DELICIOUS-Roasted-Cauliflower-Tacos-with-Adobo-Romesco-30-min-healthy-SO-flavorful-vegan-glutenfree-plantbased-cauliflower-tacos-recipe-8.jpg'
    },
    {
      type: 'Avocado',
      imgURL: 'https://www.ambitiouskitchen.com/wp-content/uploads/2018/03/tacos.jpg'
    },
    {
      type: 'Tofu',
      imgURL: 'http://www.fromachefskitchen.com/wp-content/uploads/2016/08/Tofu-and-Black-Bean-Tacos.jpg'
    },
  ],
}

const typeDefs = gql`
  type Taco {
    type: String
    imgURL: String
  }

  type Query {
    tacos: [Taco]
  }
`;

const resolvers = {
  Query: {
    tacos: () => {
      return tacos;
    },
  },
};

const apolloServer = new ApolloServer({ typeDefs, resolvers });
module.exports = apolloServer.start().then(() => apolloServer.createHandler({path: '/api/graphql',}));

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

但是,http://localhost:3000/api/graphql会让我进入Apollo Studio起始页。当我最终到达资源管理器时,我收到错误消息,指出无法访问我的服务器:OPTIONS响应缺少标头access-control-allow-methods: POST。我尝试添加cors ApolloServer,但没有成功。这是我第一次尝试让graphql端点在Next.js API中工作,我很困惑,是什么问题。

carvr3hs

carvr3hs1#

不知道你是否已经解决了这个问题,但是我也遇到了同样的问题。即使在next.js examples docs中有了最新的更新,它仍然给了我这个错误。所以我用谷歌搜索了一下,这样解决了这个问题:

const apolloServer = new ApolloServer({ typeDefs, resolvers });

const startServer = apolloServer.start();

export default async function handler(req, res) {
    res.setHeader("Access-Control-Allow-Credentials", "true");
    res.setHeader(
        "Access-Control-Allow-Origin",
        "https://studio.apollographql.com"
    );
    res.setHeader(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Headers"
    );
    res.setHeader(
        "Access-Control-Allow-Methods",
        "POST, GET, PUT, PATCH, DELETE, OPTIONS, HEAD"
    );
    if (req.method === "OPTIONS") {
        res.end();
        return false;
    }

    await startServer;
    await apolloServer.createHandler({
        path: "/api/graphql",
    })(req, res);
}
mwg9r5ms

mwg9r5ms2#

借助乔治Vlassis的回答,我在这里发布了阿波罗探索者工作所需的标题:

res.setHeader(
  'Access-Control-Allow-Origin',
  'https://studio.apollographql.com',
);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Headers', ' Content-Type');
qgelzfjb

qgelzfjb3#

如果您使用的是Apollo-server-Micro,那么您可以使用micro-cors:

yarn add micro-cors

然后,请记住导入micro_cors而不是micro-cors:

import micro_cors from "micro-cors"

const cors = micro_cors({
origin: "https://studio.apollographql.com",
allowCredentials:true,
allowMethods:["GET", "POST","PUT","DELETE"],
allowHeaders:["access-control-allow-credentials","access-control-allow-origin","content-type"]          
})

然后,用函数 Package :

const handlers= cors(async  function  handlers(req: NextApiRequest, res:   NextApiResponse) {
await startServer

if (req.method === "OPTIONS") {
    res.end()
    return false
}

await apolloserver.createHandler({ path: "/api/graphql" })(req, res);
})

export default handlers
r55awzrz

r55awzrz4#

如果您通过以下方式诊断端点:

npx diagnose-endpoint@1.1.0 --endpoint=http://localhost:3000/api/graphql

并得到如下结果:

Diagnosing http://localhost:3000/api/graphql
⚠️  OPTIONS response is missing header 'access-control-allow-methods: POST'

只需将api.bodyParser设置为false,并将其作为一个配置常量放在graphql服务器API文件的底部,如下所示:

import type { NextApiRequest, NextApiResponse } from "next";
import { gql, ApolloServer } from "apollo-server-micro";
import { ApolloServerPluginLandingPageGraphQLPlayground } from "apollo-server-core";

...

const apolloServer = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
});

const startServer = apolloServer.start();

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
): Promise<void> {
  await startServer;
  await apolloServer.createHandler({
    path: "/api/graphql",
  })(req, res);
}

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

mv1qrgav5#

@yohanes Awnser差点就为我工作了!我不得不对它做一些修改:

import { ApolloServer } from 'apollo-server-micro';
import { applyMiddleware } from 'graphql-middleware';
import schema from '../../graphql/schema';
import { dataloadersMiddleware } from '../../graphql/loaders/middleware';
import microCors from "micro-cors";
import type { NextApiRequest, NextApiResponse } from 'next';
import { ApolloServerPluginLandingPageGraphQLPlayground } from 'apollo-server-core';
import { RequestHandler } from "micro";

const cors = microCors({ 
  allowMethods: [
    'Access-Control-Allow-Methods: *',
  ],
  allowHeaders: [
    'Access-Control-Allow-Origin: *',
  ],
  allowCredentials: true,
  origin: "*"
});

const server:ApolloServer = new ApolloServer({
  schema: applyMiddleware(schema, dataloadersMiddleware),
  playground: {
    endpoint: "/api/graphql",
  },
  persistedQueries: false,
  introspection: true,
  plugins: [ApolloServerPluginLandingPageGraphQLPlayground()]
} as any);

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

const startServer = server.start()

export default cors(async function handler(req: NextApiRequest, res: NextApiResponse):Promise<void> {
  await startServer;
  await server.createHandler({ path: "/api/graphql" })(req, res);
} as RequestHandler);

相关问题