发送到Flask POST路由时,Axios数据显示为ImmutableMultiDict([]),但可与Postman一起使用

时间:2019-02-26 19:14:01

标签: reactjs post flask axios postman

我正在使用Flask创建POST方法来在我的MySQL数据库中注册一个新用户。我尝试创建一个Axios方法来从我的React JS应用程序发送POST请求。我正在使用Postman进行测试,并使用application / x-www-form-urlencoded发送。该注册可以在Postman中进行,但是数据显示为 ImmutableMultiDict([])

烧瓶代码:

@app.route('/registerUser', methods=['POST'])
def registerUser():
    data = request.form
        if len(data) is 0:
            return 'Request was empty!'
        username = data['username']
        password = data['password']
        email = data['email']
        user = User(username=username, 
                    password=password, 
                    email=email)
        db.session.add(user)
        db.session.commit()
        return 'Registration success!'
    return 'Registration failed!'

反应代码:

class Signup extends Component {
    constructor(props){
        super(props);
        this.state = {
            username: '',
            password: '',
            email: ''
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.clearInputs = this.clearInputs.bind(this);
    }

    handleChange(event){
        event.preventDefault();
        this.setState({[event.target.name]: event.target.value});
    }
    handleSubmit(event){
        event.preventDefault();
        const config = {
            headers: { 'content-type': 'application/x-www-form-urlencoded' }
        }
        axios.post(`http://localhost:5000/registerUser`, 
            this.state, config)
             .then(res => {
                alert(res.data);
             })
             .catch((err) => {
                alert(err);
             });
    }

    render(){
        return (
            <div className='signup'>
                <form onSubmit={this.handleSubmit}>
                    <label>
                        Username
                        <input type='text' name='username' 
                               value={this.state.username}
                               onChange={this.handleChange}/><br/>
                    </label>
                    <label>
                        Password
                        <input type='password' name='password' 
                               value={this.state.password} 
                               onChange={this.handleChange}/><br/>
                    </label>
                    <label>
                        Email
                        <input type='text' name='email' 
                               value={this.state.email}
                               onChange={this.handleChange}/><br/>
                    </label>
                    <input type='submit' value='Submit' /><br/>
                </form>
            </div>
        );
    }
}

export default Signup;

为什么从Axios无法正确发送数据?我在烧瓶中使用了 CORS ,Postman和Axios都应该发送相同的表单数据。

编辑:我将POST请求更改为使用request.form 但是,Postman可以工作,但Axios仍然不能。 来自邮递员:

ImmutableMultiDict([('username', 'person'), ('password', 'Password1'), ('email', 'example@example.com')])

从Axios:ImmutableMultiDict([('{"username":"someone","password":"Password1","email":"email@example.com"}', '')])

Axios配置不正确吗?

2 个答案:

答案 0 :(得分:0)

我认为您必须在JSON路由内强制将请求数据强制为registerUser 类型,因为您正尝试访问JSON响应,但您已发送了请求以application/x-www-form-urlencoded格式结束。 application/x-www-form-urlencodedW3C创建的default表单内容类型规范,通常用于发送文本/ ASCII数据。也许您可以尝试以下方法,看看是否获得预期的JSON响应:

app.route('/registerUser', methods=['POST'])
def registerUser():
    requestJson = request.get_json(force=True)

    # check that requestJson is correct if so
    # create and save your new user to your db

    return 'Registration failed!'

如果您的requestJson符合预期,则只需提取必填字段并将新用户保存到数据库即可。如果没有,请打印出您收到的请求,以了解如何对其进行适当的解析。

希望这会有所帮助!

答案 1 :(得分:0)

我发现了问题所在。默认情况下,Axios通过JSON格式发送数据。为了符合urlencoded,您需要构建一个新的URLSearchParams对象来代替发送。参见documentation

这是有效的React代码:

handleSubmit(event){
    event.preventDefault();
    const config = {
        headers: { 'content-type': 'application/x-www-form-urlencoded' }
    }
    const getParams = (obj) => {
        const params = new URLSearchParams();
        const keys = Object.keys(obj);
        for(let k of keys){
            params.append(k, obj[k]);
        }
        return params;
    }
    axios.post(`http://localhost:5000/registerUser`, 
        getParams(this.state), config)
         .then(res => {
            alert(res.data);
            this.clearInputs();
         })
         .catch((err) => {
            alert(err);
         });
}

这与我的OP Flask代码一起使用。