反应 js:axios 向 node.js api 发布请求

Posted

技术标签:

【中文标题】反应 js:axios 向 node.js api 发布请求【英文标题】:react js: axios post request to node.js api 【发布时间】:2018-12-11 07:29:33 【问题描述】:

嗨, 我在使用 axios 发送请求中的所有数据时遇到了一些问题。我创建了 node.js api,现在我想使用 axios 从我的表单发送用户注册数据,并将 react js 作为我的前端技术。

我在提交后更新了我的反应状态,现在当我想通过“内容类型”发送信息时:“应用程序/x-www-form-urlencoded”我的名字不是发送(空)和最后一个值位置最后得到 '\"'。

我在邮递员中测试了请求,它运行良好。

有什么建议吗?

我的 node.js 路由:

app.post('/users', (req, res) => 

      const user =  firstName: req.body.firstName, lastName: req.body.lastName, age: req.body.age, photo: req.body.photo, email: req.body.email, description: req.body.description, hobbies: req.body.hobbies, location: req.body.location ;

      db.collection('users').insert(user, (err, result) => 
        if (err)  
          res.send( 'error': 'An error has occurred' ); 
         else 
          res.send(result.ops[0]);
        
      );
    );

反应注册:

import React,  Component  from 'react';
import axios from 'axios';

class Register extends Component 
    state = 
        firstName: '',
        lastName: '',
        age: '',
        email: '',
        description: '',
        hobbies: '',
        location: '',
    ;

    handleFirstNameChange = event => 
        this.setState( 
            firstName: event.target.value,
        );
    

    handleLastNameChange = event => 
        this.setState( 
            lastName: event.target.value,
        );
    

    handleEmailChange = event => 
        this.setState( 
            email: event.target.value,
        );
    

    handleAgeChange = event => 
        this.setState( 
            age: event.target.value,
        );
    

    handleDescriptionChange = event => 
        this.setState( 
            description: event.target.value,
        );
    

    handleHobbiesChange = event => 
        this.setState( 
            hobbies: event.target.value,
        );
    
    handleLocationChange = event => 
        this.setState( 
            location: event.target.value,
        );
    

    handleSubmit = event => 
        event.preventDefault();

        const user = 
            firstName: this.state.firstName,
            lastName: this.state.lastName,
            age: this.state.age,
            email: this.state.email,
            description: this.state.description,
            hobbies: this.state.hobbies,
            location: this.state.location,
        ;

        //x-www-form 
        let formBody = [];
        for (let property in user) 
            let encodedKey = encodeURIComponent(property);
            let encodedValue = encodeURIComponent(user[property]);
            formBody.push(encodedKey + "=" + encodedValue);
        
        formBody = formBody.join("&");

        console.log(formBody);

        axios.post(`http://localhost:8000/users`,  formBody ,  headers:  'Content-Type': 'application/x-www-form-urlencoded'  )
          .then(res => 
            console.log(res);
            console.log(res.data);
        )
    

  render() 
    return (
      <div className="register">
        <h2>Register</h2>

        <form onSubmit=this.handleSubmit>
            <label htmlFor="firstName">First Name:</label>
            <input type="text" id="firstName" name="firstName" onChange=this.handleFirstNameChange />
            <br/>
            <label htmlFor="lastName">Last Name:</label>
            <input type="text" id="lastName" name="lastName" onChange=this.handleLastNameChange />
            <br/>
            <label htmlFor="email">Email:</label>
            <input type="text" id="email" name="email" onChange=this.handleEmailChange />
            <br/>
            <label htmlFor="age">Age:</label>
            <input type="text" id="age" name="age" onChange=this.handleAgeChange />
            <br/>
            <label htmlFor="description">Description of myself:</label>
            <input type="text" id="description" name="description" onChange=this.handleDescriptionChange />
            <br/>
            <label htmlFor="hobbies">Hobbies:</label>
            <input type="text" id="hobbies" name="hobbies" onChange=this.handleHobbiesChange />
            <br/>
            <label htmlFor="location">Location:</label>
            <input type="text" id="location" name="location" onChange=this.handleLocationChange />
            <br/>
            <input type="submit" value="Register" />
        </form>

      </div>
    );
  


export default Register;

mLab 中的数据库结果:


    "_id": 
        "$oid": "5b3af97a10d5b622289ddbbc"
    ,
    "firstName": null,
    "lastName": "test",
    "age": "222",
    "photo": null,
    "email": "test@gmail.com",
    "description": "test",
    "hobbies": "test",
    "location": "test\""

【问题讨论】:

感谢各位聪明的回答。我真的很感谢你的帮助。我还注意到我的代码的问题是在 axios 代码中添加 formBody 而不仅仅是 formBody 没有大括号。很棒的答案,谢谢。 既然可以直接使用axios发起请求,为什么还要使用axios向node.js服务器发起请求? 【参考方案1】:

为此有一个 URLSearchParams 类:

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

【讨论】:

【参考方案2】:

你可以像下面这样修改你的代码,你可以借助像https://underscorejs.org/这样的库来最小化你的代码

//nodejs route
import _ from "underscore";
app.post('/users', (req, res) => 
    //const user =  firstName: req.body.firstName, lastName: req.body.lastName, age: req.body.age, photo: req.body.photo, email: req.body.email, description: req.body.description, hobbies: req.body.hobbies, location: req.body.location ;
    const user = _.pick(req.body, 'firstName', 'lastName', 'email', 'age', 'description', 'hobbies', 'location')
    db.collection('users').insert(user, (err, result) => 
        if (err) 
            res.send( 'error': 'An error has occurred' );
         else 
            res.send(result.ops[0]);
        
    );
);

//React Registration    
import React,  Component  from 'react';
import axios from 'axios';

class Register extends Component 
    state = 
        firstName: '',
        lastName: '',
        age: '',
        email: '',
        description: '',
        hobbies: '',
        location: '',
    ;

    handleChange = event => 
        const  name, value  = event.target  //Destructure the current fields name and value
        this.setState( [name]: value );  //Sets state
    ;

    handleSubmit = event => 
        event.preventDefault();
        //Alter your Axios request like below
        axios(
            method: 'post',
            url: 'http://localhost:8000/users',
            headers: 
                'crossDomain': true,  //For cors errors 
                'Content-Type': 'application/x-www-form-urlencoded'
            ,
            data: 
                firstName: this.state.firstName,
                lastName: this.state.lastName,
                age: this.state.age,
                email: this.state.email,
                description: this.state.description,
                hobbies: this.state.hobbies,
                location: this.state.location,
            
        ).then(res => 
            console.log(res);
            console.log(res.data);
        );
       

    render() 
        return (
            <div className="register">
                <h2>Register</h2>

                <form onSubmit=this.handleSubmit>
                    <label htmlFor="firstName">First Name:</label>
                    <input type="text" id="firstName" name="firstName" onChange=this.handleChange />
                    <br />
                    <label htmlFor="lastName">Last Name:</label>
                    <input type="text" id="lastName" name="lastName" onChange=this.handleChange />
                    <br />
                    <label htmlFor="email">Email:</label>
                    <input type="text" id="email" name="email" onChange=this.handleChange />
                    <br />
                    <label htmlFor="age">Age:</label>
                    <input type="text" id="age" name="age" onChange=this.handleChange />
                    <br />
                    <label htmlFor="description">Description of myself:</label>
                    <input type="text" id="description" name="description" onChange=this.handleChange />
                    <br />
                    <label htmlFor="hobbies">Hobbies:</label>
                    <input type="text" id="hobbies" name="hobbies" onChange=this.handleChange />
                    <br />
                    <label htmlFor="location">Location:</label>
                    <input type="text" id="location" name="location" onChange=this.handleChange />
                    <br />
                    <input type="submit" value="Register" />
                </form>

            </div>
        );
    


export default Register;

【讨论】:

【参考方案3】:

当类型为Content-Type': 'application/x-www-form-urlencoded时,你必须将你的对象数据解析为string urlencoded

您可以在发送前使用 lib qs 对数据进行字符串化:

const dataSend = qs.stringify(user);

import qs from "qs";

    app.post('/users', (req, res) => 

          const user =  firstName: req.body.firstName, lastName: req.body.lastName, age: req.body.age, photo: req.body.photo, email: req.body.email, description: req.body.description, hobbies: req.body.hobbies, location: req.body.location ;

          const dataSend = qs.stringify(user);

          db.collection('users').insert(dataSend, (err, result) => 
            if (err)  
              res.send( 'error': 'An error has occurred' ); 
             else 
              res.send(result.ops[0]);
            
          );
        );

【讨论】:

以上是关于反应 js:axios 向 node.js api 发布请求的主要内容,如果未能解决你的问题,请参考以下文章

node.js / axios AUTHENTICATION_FAILURE 与 PayPal 订阅 API

DarkSky API - 未处理的拒绝错误 - ReactJS / Axios / Node.js

上传图片文件到服务器node.js express axios

从 node.js 发送结果以做出反应

使用 react/axios 的空 POST 请求

SQL - node.js express - 反应加载行为