2017-07-25 3 views
1

Je développe une application simple en utilisant Express.js et React, les deux applications dans l'environnement de développement (machine locale) se trouvent sur des ports différents, le serveur (Express) sur localhost: 3001 et Frontend (React) sur localhost: 3000.Express ne reçoit pas les paramètres via POST de React utilisant Fetch API

Le problème que j'ai est que d'essayer d'envoyer des données du Frontend en utilisant Fetch API Express ne reçoit pas les données envoyées via POST par React. J'ai fait un test en faisant un POST à ​​partir d'un formulaire normal et le serveur a accepté les paramètres que j'ai envoyés via POST, donc je pense que le problème est quelque chose avec l'appel de Javascript en utilisant Fetch API.

Dans Express, j'ai déjà installé le module cors pour accepter les demandes qui ne sont pas du même domaine mais le problème persiste. Ci-dessous un extrait de code des deux pour une meilleure compréhension.

... 
// handler recieves the 'e' event object 
formPreventDefault(e) { 
    var headers = new Headers(); 
    headers.append('Accept', 'application/json, application/xml, text/plain, text/html, *.*'); 
    headers.append('Content-Type', 'multipart/form-data; charset=utf-8'); 
    headers.append('Access-Control-Allow-Origin', '*'); 
    headers.append('Access-Control-Allow-Headers', 'Content-Type'); 

    var myForm = document.getElementById('myForm'); 
    var formData = new FormData(myForm); 
    formData.append('email', '[email protected]'); 
    formData.append('password', '12345'); 

     var options = { 
     headers: headers, 
     mode: 'no-cors', // crossdomain * 
     method: 'post', 
     body: JSON.stringify({ 'email': '[email protected]', 'password': '12345' }) // formData 
    }; 

    var request = new Request('http://localhost:3001/user/signin', options); 

    fetch(request).then(function(response) { 
     console.log("Success"); 
     return response; 
    }).then(function(json) { 
     console.log(json); 
     }).catch(function(err) { 
     console.log("Error " + err); 
    }) 

    // prevent submit form 
    e.preventDefault(); 

    } 

    render() { 
    return (
     <div className="row"> 
     <div className="col-md-4 "> 
      <form id="myForm" action="http://localhost:3001/user/signin" method="post" onSubmit={this.formPreventDefault}> 
       <div className="form-group"> 
        <label htmlFor ="email">Email address</label> 
        <input type="email" className="form-control" id="email" name="email" placeholder="Email" /> 
       </div> 
       <div className="form-group"> 
        <label htmlFor ="password">Password</label> 
        <input type="password" className="form-control" id="password" name="password" placeholder="*******" /> 
       </div> 
       <button type="submit" className="btn btn-default">Submit</button> 
       </form> 
     </div> 
     </div> 
    ); 
    } 
} 
... 

express contrôleur

... 
// Handle User Sign In on POST 
exports.user_create_post = function(req, res) { 
    console.log(req.body); // This always returns an empty value 
    //Check that the name field is not empty 
    req.checkBody('email', 'Email address is required').notEmpty(); 
    req.checkBody('password', 'Password is required').notEmpty(); 

    //Run the validators 
    var errors = req.validationErrors(); 

    //Create a genre object with escaped and trimmed data. 
    var user = new User(
     { email: req.body.email, password: req.body.password } 
    ); 

    if (errors) { 
     //If there are errors render the form again, passing the previously entered values and errors 
     // res.render('users/sign_up', { title: 'Sign Up', user: user, errors: errors }); 
     res.json({ user: user, errors: errors }); 
     return; 
    } 
    else { 
     // Data from form is valid. 
     //Check if User with same email already exists if not the new user is saved 
     User.findOne({ 'email': req.body.email }) 
      .exec(function(err, found_user) { 
       if (err) { return next(err); } 

       if (found_user) { 
        //User exists, redirect to the home page 
        // res.render('users/home', { title: 'Home', user: found_user }); 
        res.json({ user: found_user }); 
       } 
       else { 
        // Save user 
        user.save(function (err) { 
         if (err) { return next(err); } 

         // Create session 
         req.session.user_id = user._id.toString(); 

         // User saved. Display user profile page 
         // res.render('users/home', { title: 'Home', user: user }); 
         res.json({ user: user }); 
        }); 

       } 

      }); 
    } 
}; 
... 

Toute aide est la bienvenue

+0

Puisque les deux expriment et ne sont pas réagir de la même origine, pour la demande de récupération, vous devez vous assurer '{mode: 'CORS'}' est réglé pour fetch options. Il peut être utile de vérifier si cors fonctionne ou s'il y a du code d'erreur HTTP retourné dans la requête en enregistrant l'objet 'response' ou la valeur response.status dans le premier .then() suivant fetch(). En outre, il peut être utile de vérifier la requête/réponse HTTP de l'API en vérifiant l'onglet réseau de la console développeur sur votre navigateur pour voir s'il y a un problème avec la requête. –

+0

J'ai le "mode: 'no-cors'" dans l'option du fetch.C'est-à-dire que l'objet Response retourne de la requête au serveur Express: Response {type: "opaque", url: "", redirigé: false, status: 0, ok: false, statusText: "", en-têtes: en-têtes, bodyUsed : false} – Wilcho

Répondre

-1

Si votre environnement de production sera l'hôte à la fois le frontend et le serveur, vos demandes éventuellement ne doivent faire face à CORS. Dans ce cas, je suggère de cibler le port 3000 dans votre frontend réagir à la demande de récupération, et en utilisant la fonctionnalité "proxy" Proxying API Requests in Development sur votre serveur Frontend pour le développement.

Fondamentalement, mettre dans votre package.json

"proxy": "http://localhost:3001", 

et changer votre demande à:

var request = new Request('http://localhost:3000/user/signin', options); 

EDIT Nettoyage de demande d'extraction nécessaire pour que cela fonctionne:

fetch('http://localhost:3000/user/signin', { 
    method: 'POST', 
    headers: { 
     'Content-Type': 'application/json', 
    }, 
    body: JSON.stringify({ 'email': '[email protected]', 'password': '12345' }) // formData 
}).then(function(response) { 
... 
+0

Cela ne fonctionne pas – Wilcho

+0

Vous devrez être plus précis. Qu'est-ce qui n'a pas fonctionné? La demande n'a jamais atteint votre serveur principal? La demande a atteint mais le contenu est vide? – nAv

+0

S'il atteint votre serveur mais vous ne pouvez pas lire le contenu, au lieu d'utiliser 'multipart/form-data; charset = utf-8 'pour votre Content-Type essayez de définir votre en-tête à' Content-Type ':' application/json ' – nAv

0

Je l'ai compris comment résoudre le problème, voici le code avec l'aide de ce poste https://github.com/matthew-andrews/isomorphic-fetch/issues/34.

J'espère que quelqu'un aide

Merci pour l'aide me

... 
// handler recieves the `e` event object 
    formPreventDefault(e) { 

     var headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 

     var email = document.getElementById('email').value; 
     var password = document.getElementById('password').value; 

     if(email !== '' && password !== '') { 

      var options = { 
       method: 'POST', 
      headers: headers, 
      mode: 'cors', 
      cache: 'default', 
       body: JSON.stringify({ 'email': email, 'password': password }) // formData 
      }; 

      var request = new Request('http://localhost:3001/user/signin', options); 

      fetch(request).then(function(response) { 

      console.log("Success"); 
       return response; 

      }).then(function(json) { 

      console.log(json.errors); 

      }).catch(function(err) { 

      console.log("Error " + err); 

      }) 

     } 

     // prevent submit form 
     e.preventDefault(); 

    } 
... 
0

Votre principal problème est que vous ne définissez pas votre corps de demande d'être vos données de formulaire. Au lieu de cela, vous encodez manuellement les données de votre formulaire en tant que json. Big tipoff: vous créez la variable formData mais ne l'utilisez jamais nulle part.

Essayez ceci:

options = { 
    headers: headers, 
    mode: 'no-cors', // crossdomain * 
    method: 'post', 
    body: formData 
};