Express不会使用Fetch API从{React}通过POST接收参数

时间:2017-07-25 13:38:10

标签: javascript reactjs express fetch

我正在使用Express.js和React开发一个简单的应用程序,开发环境(本地机器)中的两个应用程序都在不同的端口上,localhost:3001上的服务器(Express)和localhost上的前端(React): 3000。

我遇到的问题是尝试使用Fetch API Express从前端发送数据不会收到React通过POST发送的数据。我做了一个测试从普通表单执行POST,服务器确实接受了我通过POST发送的参数,所以我认为这个问题是使用Fetch API从Javascript调用的。

在Express中我已经安装了cors模块来接受不属于同一域的请求,但问题仍然存在。

以下是两段代码,以便更好地理解。

...
// 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', 'demo@domain.com');
    formData.append('password', '12345');

        var options = {
        headers: headers,
        mode: 'no-cors', // crossdomain *
        method: 'post',
        body:  JSON.stringify({ 'email': 'admin@domain.com', '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 Controller

...
// 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 });
                     });

                 }

             });
    }
};
...

欢迎任何帮助

3 个答案:

答案 0 :(得分:0)

如果您的生产环境将托管前端和服务器,您的请求最终将不必处理CORS。在这种情况下,我建议在您的前端反应获取请求中使用端口3000,并使用前端服务器上的“代理”功能Proxying API Requests in Development进行开发。

基本上,把它放在你的package.json

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

并将您的请求更改为:

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

修改 清除此工作所需的获取请求:

fetch('http://localhost:3000/user/signin', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({ 'email': 'admin@domain.com', 'password': '12345' }) // formData
}).then(function(response) { 
...

答案 1 :(得分:0)

我已经弄明白了如何解决问题,这篇文章是在https://github.com/matthew-andrews/isomorphic-fetch/issues/34帖子的帮助下完成的。

我希望能帮助某人

感谢您的帮助

...
// 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();

  }
...

答案 2 :(得分:0)

您的主要问题是您没有将请求正文设置为表单数据。而是手动将表单数据编码为json。 Big tipoff:您创建了formData变量但从未在任何地方使用它。

试试这个:

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