CORS blocking is preventing Next JS due to lack of HTTP OK response status

When utilizing GraphQL to facilitate communication between a client and server across different domains, I took the necessary steps to enable CORS on my API website by referring to the documentation provided by Vercel. However, it appears that I am encountering an error that states:

blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Here is a snippet of the code I implemented in GraphQL:

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

Additionally, within the API website, the next.config.js file contains the following configuration:

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",
          },
        ],
      },
    ];
  },
};

I am unsure whether there is an issue with my next.config.js setup or if the problem lies within the Apollo Client implementation as I do not utilize Express. Any insights or suggestions would be greatly appreciated. Thank you!

Answer №1

Utilizing the latest version of next.js

/api/graphql

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);

/utils/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;
  }
  await fn(req, res);
};

export default allowCors;

Answer №2

To resolve the issue, I implemented an alternative approach to configuring CORS by using:

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)
}

I was confident that this solution would be effective because of the condition set on the req.method === OPTIONS part, which addressed the missing HTTP ok status in the request. Instead of manually passing the header, I leveraged the existing apolloServer handler utilized in my API:

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

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

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

Subsequently, I incorporated it and exported

export default allowCors(handler)
.

Credit goes to @slideshowbarker for the valuable insight!

Answer №3

Give this a shot, it should do the trick:

const connection = new ApolloClient({
  dataStore: new InMemoryCache(),
  serverEndpoint: **update**,
  securityOptions: {
    'Access-Control-Allow-Origin': '*'
  }
});

Answer №4

import { ApolloServer } from "apollo-server-micro";
import allowCors from "../../../utils/cors";
import typeDefs from "../../../graphql/schemas";
import resolvers from "../../../graphql/requests";

const apolloServer = new ApolloServer({
  typeDefs: typeDefs,
  resolvers,

  // playground: true,
  introspection: true,
  context: ({ req }) => {
    return {
      headers: req.headers,
    };
  },
  cache: "bounded",
  // plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
});

const startServer = apolloServer.start();

async function handler(req, res) {
  res.setHeader("Access-Control-Allow-Origin", "*");

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

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

export default allowCors(handler);

utils/cors.js

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);
};

export default allowCors;

However, the same issue persists and I am unable to comprehend the error

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The issue arises when trying to set headers after they have already been sent in the Google Maps Places API and Express

I have been exploring the implementation of google maps places api to create a basic web application. Currently, my approach involves fetching data from the api and storing it in my mongodb database. Utilizing the google maps places npm module @google/map ...

Travis CI: encountering difficulties while attempting to update npm to a newer version

Attempting to update the npm version being used by Travis CI in the .travis.yml configuration file: language: node_js node_js: 0.12 before_install: npm install -g npm@latest However, after checking the logs of the Travis job, it seems that nothing has ch ...

Error 401: Unauthorized access detected while handling a Webhook

My goal is to handle a webhook sent by the authentication provider Clerk when a new user is created. To test this process locally, I initially used localtunnel without success and then switched to ngrok. Upon receiving the webhook at https://13f1-...-859 ...

Tips for submitting a request following a change in the variable

I am in the process of developing a React application and I have implemented Auth0 for authentication. My goal is to initiate an HTTP request upon page refresh, but only if the variable isLoading is false. This way, I can access the user object once the ...

Can you explain the distinction between <div /> and <div></div> or <Component /> and <Component> </Component>?

Can you explain the distinctions between <div />, <div></div>, <Component />, and <Component> </Component> for me? <Layout home> \<section\> \<h2\>Blog\</h2\> ...

Tips on obtaining a Firebase ID

Does anyone have a solution for retrieving the unique id from Firebase? I've attempted using name(), name, key, and key() without any success. Although I can view the data, I'm struggling to find a way to retrieve the id. This information is cru ...

Dockerized NextJS and Strapi setup

I am currently facing challenges in containerizing a NextJS application along with a Strapi application using Docker. My project structure is as follows: /project /strapi ... Dockerfile /nextjs ... Dockerfile docker-compose.yml Ultimat ...

Field must have a base type specified to proceed

Currently, I am in the process of developing a discord.js bot. The structure I have set up involves a folder that contains all the commands, and when a command is called, index.js directs it to the appropriate file. However, when attempting to run the bot, ...

When switching between npm and ionic in various directories, the versions displayed may vary

I've encountered a strange issue while trying to install ionic and npm. Up until yesterday, I had no problem building an app. However, after attempting to update my ionic version to 2.1.18, I ran into some difficulties. When I checked ionic -v in ...

NextAuth asynchronous function completion occurring before value is returned

When signing in, I am working on querying FirestoreDB and then retrieving the user data or null. I have attempted to use async await for this purpose, but the dependent code executes before the database query is complete. This issue is evident when "CORRE ...

Has anyone been able to establish a successful connection between a NodeJS project and SQL Server using AAD-Managed identity?

I came across some code from the Microsoft docs, but unfortunately, it doesn't seem to be functioning correctly. If anyone has any insights on this issue, I would greatly appreciate it. Furthermore, I am curious if it is even possible to achieve what ...

Encountering a display issue within a port using Express

Recently, I enrolled in an advanced ExpressJS course. While exploring the course website, I stumbled upon the "hello world" section. Intrigued, I decided to copy and paste the code provided below: const express = require('express') const app = ex ...

What methods are there for incorporating a sub-component from a React client into a React server component?

Using Next.JS 13.4.19 and the new app folder to enable React Server Components is posing a challenge when attempting to incorporate client sub-components (such as <ClientComponent.SubComponent \>) within a server component. The file ClientTest. ...

Is there a way to access environment variables within npm or package.json configuration?

I'm working on creating a package.json file to ensure that when my NodeJS app is deployed on Heroku, it will execute the scripts.postinstall step using an environment variable. Here is an example: ... "scripts": { "postinstall": "command $ENV_VAR"} ...

Top ways to configure dynamic route parameter in express

To ensure that going to www.myapp.com/(username) will take you to the specific user's page in my app, I have structured the routes with the following handler: app.get('/:username', function(){ //retrieve and render user profile data from ...

Encountered a problem when attempting to establish a socket connection with node js express and socket.io within my project directory on a

I'm currently facing an issue with creating a socket connection using node js express and socket.io in my project folder on a Linux(Ubuntu) server. Despite installing nodejs, npm, socketio, and express, I am unable to establish the socket connection. ...

Node.js vulnerability labeled as CVE-2021-38628

Description: Enhance security measures by disabling the use of TLSv1.0 protocol and transitioning to a more secure option like TLSv1.2. To perform a manual test, utilize the following openssl commands: openssl s_client -connect ip:port -tls1. If succes ...

Managing registration with an existing email address in Supabase

Currently, I am working on implementing a sign-up functionality using Supabase and I want to be able to inform the user if they try to sign up with an email that already exists in the system. However, I am facing a challenge in identifying this particular ...

Setting up Node and NPM on Laradock can streamline your development

After carefully following the steps outlined in the documentation to enable NPM on my workspace, I encountered an issue. Upon running docker-compose exec workspace bash and checking for node -v, it was not installed as expected. The document does not pro ...

Changing the structure of a JSON array in JavaScript

I'm currently developing an ExpressJS application and I need to send a post request to a URL. My data is being retrieved from a MS SQL database table using Sequelize, and the format looks like this: [ { "x":"data1", "y":& ...