请求正文与提交的数据不同

时间:2017-12-12 19:23:30

标签: javascript forms reactjs express

我正在使用具有表单的React应用程序,并将其发送到Express路由以将数据发布到API。 API文档中的一个示例要求表单数据对象如下所示:

var form_data = {
      "email": "email@example.com",
      "first_name": "John",
      "last_name": "Doe",
      "p[7]": "7",
      "status[7]": "1"
      "p[12]": "12",
      "status[7]": "1"
    };

p[7]p[12]表示要添加用户的列表ID。我正好从API中获取活动列表并填充选择菜单供用户选择。当用户提交表单时,我将控制台记录数据,并且所有内容都显示为:

{email: "testemail@example.com", p[10]: "10", p[9]: "9"}

正如您所看到的,响应具有我从菜单中选择的正确ID输出。当我提交表单并将其发送到Express路线以将其推送到API时,数据会突然改变。从Express服务器上的控制台日志中:

{ email: 'testemail@example.com', p: [ '9', '10' ] }

我不确定发送此数据的地方出了什么问题。以下是从React应用程序发送数据的方法:

sendData(){
    let formData = {
      email: this.state.email_address
    }

    let selectValues = this.state.value.split(',');

    for (var i = 0; i < selectValues.length; i++) {
      formData[`p[${selectValues[i]}]`] = selectValues[i]
    }

    // outputs as expected 
    console.log(formData)

    // Send the form data.
    var xmlhttp = new XMLHttpRequest();
    var _this = this;
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState === 4) {
        var response = JSON.parse(xmlhttp.responseText);
        if (xmlhttp.status === 200 && response.status === 'OK') {
          _this.setState({ type: 'success', message: 'We have received your message and will get in touch shortly. Thanks!' });
        }
        else {
          _this.setState({ type: 'danger', message: 'Sorry, there has been an error. Please try again later or send us an email at info@example.com.' });
        }
      }
    };
    xmlhttp.open('POST', 'http://localhost:5000/send-job-signup', true);
    xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xmlhttp.send(this.requestBuildQueryString(formData));
  }

我从路线中删除了所有API连接,但它很直接:

.post('/send-job-signup', (req, res) => {

  console.log(req.body);

  res.send(req.body)
} )

什么会导致响应将数据推送到一个p密钥?感谢您的投入!

1 个答案:

答案 0 :(得分:2)

正如@Peter在评论中提到的那样,问题的根源是qs使用的body-parser库。

阻止这种情况的关键是在extended: false中设置urlencoded。所以在我的Express应用程序的index.jsSee docs on body-parser):

.use(bodyParser.urlencoded({
      extended: false
  }))

这使得每个p密钥保持独立,允许API执行其操作。