rstack3000
rstack3000

Reputation: 43

React Express Fetch Post CORS error: Response to preflight request doesn't pass access control check: It does not have HTTP ok status

I'm trying to set up a basic user signup form with React, Node, and Express, and using fetch. However, I'm getting the following errors in the Chrome console when I try and send a post request: 1) "OPTIONS http://localhost:7001/v1/register 500 (Internal Server Error)" 2) "Access to fetch at 'http://localhost:7001/v1/register' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."

My eventual goal is to save the user's email and password in a database, but for now all I want is for the request to go through to the backend and have the backend log the body to make sure everything works. I've tried several different ways of setting headers, and I have no idea what's wrong. Below is the code.

Frontend form submit function:

handleSubmit(e) {
    e.preventDefault();
    const signUpInfo = this.state; // { email: '[email protected]', password: '123' }
    console.log(signUpInfo);

    fetch('http://localhost:7001/v1/register', {
      method: 'POST',
      body: JSON.stringify(signUpInfo),
      headers: {
        'Content-Type': 'application/json'
      }
    })
    .then(res => res.json())
    .then(response => console.log('Success:', response))
    .catch(error => console.error('Error:', error));
  }

server.js

const express = require('express');
const compression = require('compression');
const cfg = require('config');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser');
const config = require('config');

const app = express();

app.use(compression());
app.use(bodyParser());
app.use(cookieParser());


// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(express.static(path.join(__dirname, 'public')));

app.use(function(req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
    res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
    res.setHeader('Access-Control-Allow-Credentials', true)
    next();
});

// CONTROLLERS
const userController = require('./controllers/userController.js');

// ROUTES
app.post('/v1/register', userController.register);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

app.listen('7001', function() {
    console.log('API server listening on port 7001!');
});


module.exports = app;

userController.js

exports.register = async (req, res, next) => {
  try {
    console.log(req.body);

    res.status(200).json({ status: 200, data: req.body, message: "test" });
  } catch (err) {
    console.log(err);
    res.status(500).json({ status: 500, data: null, message: err });
  }
}

All I'm looking for is for the backend console to print out the body. It works with axios and $.ajax, but not with fetch. I've also tried using a proxy server to no avail (and would like to get it to work without a proxy).

Not sure if this is relevant, but I'm using Chrome as the browser and Sequelize.

Any help would be greatly appreciated. I feel like I'm missing something fundamental. Any helpful articles to deepen my learning would be a plus!

Upvotes: 4

Views: 8625

Answers (2)

Khaled Rakhisi
Khaled Rakhisi

Reputation: 325

First Install "cors":

npm i cors

Second import "cors":

cors = reqquire("cors");

Third use "cors":

const app = express();
app.use("*", cors());

Upvotes: 0

AConsumer
AConsumer

Reputation: 2771

Instead of using

const app= express();

try to use

const app=express().use('*', cors());

and remove

app.use(function(req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
    res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
    res.setHeader('Access-Control-Allow-Credentials', true)
    next();
});

see if this works.

Upvotes: 3

Related Questions