troubleshooting Question

Why Does This Make a Difference?

Avatar of Bruce Gust
Bruce GustFlag for United States of America asked on
JavaScriptNode.js
7 Comments3 Solutions153 ViewsLast Modified:
Here's my initial code:

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    'Access-Control-Allow-Methods',
    'GET, POST, PUT, PATCH, DELETE'
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  next();
});

This is part of a Node.js tutorial I'm going through. It's a React front end that interacts with an API which utilizes GraphQL.

The code that I've got above is from the "app.js" file that's a part of the API. I've got the code in its entirety below:

const path = require("path");

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const multer = require("multer");
const graphqlHttp = require('express-graphql');

const graphqlSchema = require('./graphql/schema');
const graphqlResolver = require('./graphql/resolvers');

const app = express();

const fileStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "images");
  },
  filename: (req, file, cb) => {
    //cb(null, uuidv4());
    cb(null, file.originalname);
  }
});

const fileFilter = (req, file, cb) => {
  if (
    file.mimetype === "image/png" ||
    file.mimetype === "image/jpg" ||
    file.mimetype === "image/jpeg"
  ) {
    cb(null, true);
  } else {
    cb(null, false);
  }
};

app.use(bodyParser.json());
app.use(
  multer({
    storage: fileStorage,
    fileFilter: fileFilter
  }).single("image")
);
app.use("/images", express.static(path.join(__dirname, "images")));

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    'Access-Control-Allow-Methods',
    'GET, POST, PUT, PATCH, DELETE'
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  if(req.method==='OPTIONS') {
	  return res.sendStatus(200);
  }
  next();
});

app.use(
	'/graphql', 
	graphqlHttp({
		schema: graphqlSchema, 
		rootValue: graphqlResolver, 
		graphiql:true, 
		formatError(err) {
			if(!err.originalError) {
				return err;
			}
			const data = err.originalError.data;
			const message = err.message || 'An error occurred.';
			const code = err.originalError.code || 500;
			return { message: message, status: code, data: data };
		}
	})
);

app.use((error, req, res, next) => {
  console.log(error);
  const status = error.statusCode || 500;
  const message = error.message;
  const data = error.data;
  res.status(status).json({ message: message, data: data });
});

mongoose
  .connect(
    "my database"
  )
  .then(result => {
    const server = app.listen(8080);
  })
  .catch(err => console.log(err));


Everything about the app is sound, as far as there being no syntactical errors. But every time I attempted to set up a user, I would get this error:

Access to fetch at 'http://localhost:8080/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

After researching what CORS was and trying different things, I downloaded the sample code from the tutorial and was able to identify this one line as being the "thing" that made all the difference. I've got it in bold below:

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    'Access-Control-Allow-Methods',
    'GET, POST, PUT, PATCH, DELETE'
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
[b] if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }[/b]
  next();
});

At that point, the error went away.

Why?
ASKER CERTIFIED SOLUTION
Zvonko
Systems architect
Join our community to see this answer!
Unlock 3 Answers and 7 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 3 Answers and 7 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros