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
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!
Advertisement
Answer
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 SlimContainer(); $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()); }; };