Web前端之路让前端飞Web 前端开发

填坑笔记—Nodejs获取form-data数据

2017-08-14  本文已影响12591人  7天苹果

原本的要练习cookie-session登陆的方法,顺便想要使用一下原生的xhr对象,却发现了问题,使用原生xhr对象发送post请求时,我将要发送的数据放入formData中并在后台接收,这里formData是XMLHttpRequest 2.0的新的数据类型:

XMLHttpRequest Level 2添加了一个新的接口FormData. 利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个”表单”。比起普通的ajax, 使用FormData的最大优点就是我们可以异步上传一个二进制文件。

刚开始就出错了:

前端代码:

<script>
   function register() {
       const username = document.getElementById('username').value;
       const psw = document.getElementById('psw').value;

       let formData = new FormData();
       formData.append('username', username);
       formData.append('psw', psw);
       console.log(formData);

       var xhr = new XMLHttpRequest();

       xhr.onreadystatechange = function () {
           if (xhr.readyState == 4) {
               if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                        alert(xhr.responseText);
                    } else {
                        alert("Response was unsuccessful:" + xhr.status);
                    }
                }
            };

            xhr.open("post", "/register", true);
            xhr.send(formData);
        }
    </script>
</head>
<body>
<div class="main">
        用户名:<input type="text" id="username" name="username"/>
        密码:<input type="password" id="psw" name="psw"/>
        <div class="button">
            <button class="btn btn-primary">登陆</button>
            <button class="btn btn-primary" onclick="register()">注册</button>
        </div>
</div>

想在后台接收formData的数据,返回却是个空对象。

//后台代码
const path = require('path');
const express = require('express');

const app = new express();
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.use(express.static('public'));

app.post('/register',(req,res)=>{
    console.log(req.body);
    res.send("ok");
});
app.listen(3000, () => {
    console.log('server started at http://localhost:3000');
});

module.exports = app;
空对象

于是在浏览器查看请求信息,发现formData的数据被放在了Request Payload中:

FormData提交格式的每个数据分三部分:

那么为什么它会保存在Request Payload中而不是请求信息的body中呢?

因为HTTP POST表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,而使用原生AJAX的POST请求如果不指定请求头RequestHeader,默认使用的Content-Type是text/plain;charset=UTF-8。Content-Type不是application/x-www-form-urlencoded的POST请求是不会读取请求体数据和进行相应的参数处理的。

解决方案:

1、设置请求的Content-type字段为application/x-www-form-urlencoded

xhr.open("post", "/register", true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(formData);

此时在后台可以获取到req.body中的数据。

2、使用express的中间件connect-multiparty ,它是专门处理此类post数据相关的依赖包。
安装依赖以后在服务器端使用:

var multipart = require('connect-multiparty');

var multipartMiddleware = multipart();
app.post('/register', multipartMiddleware, function(req, res) {
    console.log('get FormData Params: ', req.body);
});

如此可以获得formData中的数据:

demo地址:https://github.com/lipeishang/JS-formData

上一篇 下一篇

猜你喜欢

热点阅读