javascriptphpreactjscorsslim

CORS Errors only with 400 bad request react fetch request


I'm trying to make 'POST' request in react but i'm getting a few problems regarding CORS. I was just following what console says and fix them in server side [which is PHP] and client side everything works fine when the status is 200 but when status 400 it shows

login:1 Failed to load http://192.168.0.102/API/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 400. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

I've tried to add mode: 'no-cors' but that's doesn't work it shows

Uncaught (in promise) SyntaxError: Unexpected end of input

Server Side 'PHP Slimframework' headers:

$app->add(function ($req, $res, $next) {
    $response = $next($req, $res);
    return $response
        ->withHeader('Access-Control-Allow-Origin', 'http://localhost:3000')
        ->withHeader('Origin', 'http://localhost:3000')
        ->withHeader('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, X-Auth-Token')
        ->withHeader('Access-Control-Allow-Credentials', 'true')
        ->withHeader('Access-Control-Request-Headers', 'Origin, X-Custom-Header, X-Requested-With, Authorization, Content-Type, Accept')
        ->withHeader('Access-Control-Expose-Headers', 'Content-Length, X-Kuma-Revision')
        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
});

Client Side

src/actions/userActions.js

export function loginUsers(userData) {
    return new Promise((resolve, reject) =>{
            fetch(URL,{
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'application/json',
                },
                credentials: 'include',
                //mode: 'no-cors', // if it's on it will show Uncaught (in promise) SyntaxError: Unexpected end of input
                body: JSON.stringify(userData),
            })
                .then((response) => response.json())
                .then((responseJson) =>{
                    resolve(responseJson);
                })
                .catch((error) =>{
                    reject(error)
                })
        })
}

src/components/layout.js

import React, {Component} from 'react';
import { loginUsers } from '../actions/usersAction';

class Layout extends Component {
    constructor(props){
        super(props);
        this.state = {
            username: '',
            password: '',
        };
        this.handleLogin = this.handleLogin.bind(this);
        this.onChange = this.onChange.bind(this);
    }

    onChange(e){
        this.setState({ [e.target.name] : e.target.value });
    }


handleLogin(){
        if (this.state.username && this.state.password){
            loginUsers(this.state).then((result) =>{
                let responseJSON = result;
                console.log(responseJSON);
            });
        }
    }

    render() {
        return (
            <div className="App">
                <input type="text" onChange={this.onChange} name="username" />
                <input type="password" onChange={this.onChange} name="password" />
                <button onClick={this.handleLogin}>Sign in</button>
            </div>
        );
    }
}




export default Layout;

here screenshot getting this error only with bad request like 400 enter image description here

Please let me know if I miss out any information.

If this has already been asked, I would greatly appreciate if you are able to point me in the right direction.

Thank you so much!


Solution

  • The problem is with your "php exceptions" on the server-side, When you are throwing an error the headers are not set.

    You have to set a few header when you throw the exceptions:

    $c = new \Slim\Container();
    $c['errorHandler'] = function ($c) {
        return function ($request, $response, $exception) use ($c) {
            return $c['response']->withStatus(500)
        ->withHeader('Access-Control-Allow-Origin', 'http://localhost:3000')
        ->withHeader('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, X-Auth-Token')
        ->withHeader('Access-Control-Allow-Credentials', 'true')
        ->withHeader('Access-Control-Expose-Headers', 'Content-Length, X-Kuma-Revision')
        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS')
        ->write(exception->getMessage());
                                 
        };
    };