web-dev-qa-db-fra.com

Les erreurs CORS seulement avec 400 requêtes incorrectes réagissent à la requête de récupération

J'essaie de faire la demande 'POST' en réaction mais j'ai quelques problèmes avec CORS. Je ne faisais que suivre ce que dit la console et les corriger dans côté serveur [qui est PHP] et côté client tout fonctionne correctement lorsque le statut est 200 mais que le statut 400 indique 

login: 1 Impossible de charger http://192.168.0.102/API/ : No L'en-tête 'Access-Control-Allow-Origin' est présent sur le .__ demandé. Ressource. Origin ' http: // localhost: 3000 ' n'est donc pas autorisé accès. La réponse avait le code de statut HTTP 400. Si une réponse opaque répond à vos besoins, définissez le mode de la requête sur "aucun cors" pour récupérer le fichier ressource avec CORS désactivé.

J'ai essayé d'ajouter mode: 'no-cors' mais ça ne marche pas, ça se voit

Uncaught (promis) SyntaxError: Fin d'entrée inattendue

En-têtes 'PHP Slimframework' côté serveur:

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

Côté client

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;

capture d’écran obtenir cette erreur uniquement avec une requête incorrecte comme 400  enter image description here

S'il vous plaît laissez-moi savoir si je manque toute information.

Si cela a déjà été demandé, j'apprécierais grandement si vous pouviez me diriger dans la bonne direction.

Merci beaucoup!

4
Liam

Le problème vient de vos exceptions côté serveur. Lorsque vous générez une erreur, les en-têtes ne sont pas définis. 

Donc, ce que vous devriez faire, c'est avec une réponse d'erreur puisque vous avez dit que cela fonctionnait avec 200 codes d'état. 

Vous devez définir l'en-tête lorsque vous lancez les 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-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')
    ->write(exception->getMessage());

    };
};
2
Adam

Le problème est avec la demande que vous faites! 

Le serveur ne définira pas l'en-tête 'Access-Control-Allow-Origin' lorsque vous ferez une mauvaise requête, il la rejettera et causera à son tour l'erreur CORS.

Corrigez la cause de la mauvaise demande, le paramètre manquant généralement et vous êtes prêt à partir !!!

2
Mr.Arjun

Vous devez ajouter à vos en-têtes d’objet une clé Access-Control-Allow-Origin avec la valeur http://localhost:3000 (votre URL frontale), ou supprimer 

-> withHeader('Access-Control-Allow-Origin', 'http://localhost:3000')

dans votre backend (mais c'est un problème de sécurité)

0
tolotrasmile