Express无法通过req.body获取请求传递的数据解决方法

目录
  • 前言
  • 1、问题描述
  • 2、 解决办法
    • 2.1 解决JSON内容格式
    • 2.2、解决x-www-form-urlencoded内容格式
  • 3、附
    • 3.1、获取get请求参数
    • 3.2、封装XMLHttpRequest
  • 4、总结

前言

最近尝试重新封装XMLHttpRequest,在发post请求的时候,发现express通过req.body获取不到数据,req.body打印出来是一个空对象。

网上也试了网上各种办法,还是不成功,最后发现需要在XMLHttpRequest请求时设置一个请求头,来标识发送过去数据的类型。

1、问题描述

服务端代码如下:创建了一个/login请求,在控制台输出请求数据。

// 创建应用对象
const express = require('express');
const bodyParser = require('body-parser');
// 创建应用对象
const app = express();
app.use((req,res,next)=>{
    //针对跨域进行配置,允许任何源访问
    res.header('Access-Control-Allow-Origin', "*")
    next()
})
// 创建路由规则
app.post("/login", (req,res) =>{
    // 输出req.body
    console.log("req.body:", req.body);
    res.send("login success")
})
// 监听端口启动服务
app.listen(8002,() => {
    console.log("服务已启动,8002端口监听中...");
})

前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="login">登录</button>
    <script>
        let dom = document.getElementById("login")
        url = "http://localhost:8002/login"
        dom.addEventListener("click",function(){
            let xml = new XMLHttpRequest()
            let data = {"username":"test","password":"123"}
            xml.onreadystatechange = function(){
                if(xml.readyState == 4){
                    console.log(xml.responseText);
                }
            }
            xml.open("post", url , true)
            xml.send(JSON.stringify(data))
        })
    </script>
</body>
</html>

明明已经通过xml.send(JSON.stringify(data))已经将数据转换成json格式传到后端,我们可以打开network查看。

但是express中就是获取不到{"username":"test","password":"123"},控制台输出了一个空对象。

2、 解决办法

2.1 解决JSON内容格式

查了网上的教程,可以通过引入中间件'body-parser':它是一个HTTP请求体解析中间件,它用于解析客户端请求的body中的内容,如application/x-www-form-urlencodedapplication/json这两种常用的内容格式。

配置后代码如下:

// 创建应用对象
const express = require('express');
// 执行npm install body-parser之后再引入
const bodyParser = require('body-parser');
// 创建应用对象
const app = express();
// 处理application/json内容格式的请求体
app.use(bodyParser.json());
app.use((req,res,next)=>{
    //实验验证,只需要设置这一个就可以进行get请求
    res.header('Access-Control-Allow-Origin', "*")//配置8080端口跨域
    next()
})
// 创建路由规则
app.post("/login", (req,res) =>{
    // console.log(req);
    console.log("req.body:", req.body);
    res.send("login success")
})
// 监听端口启动服务
app.listen(8002,() => {
    console.log("服务已启动,8002端口监听中...");
})

但是依旧获取不到!!!

原因:在请求中,没有设置请求头,也就是没有指明你传递的是什么格式的数据,需要通过xml.setRequestHeader("Content-Type","application/json")或者通过xml.setRequestHeader("Content-Type","application/x-www-form-urlencoded");设置请求头中Content-Type值。

前端请求中补充xml.setRequestHeader("Content-Type","application/json")

xml.open("post", url , true)
// 添加Content-Type这个请求头
xml.setRequestHeader("Content-Type","application/json");
xml.send(JSON.stringify(data))

同时在服务端配置跨域请求允许的访问头,如果不配置res.header('Access-Control-Allow-Headers', 'Content-Type'),则会出现以下提示content-type is not allowed

跨域配置,配置请求中可携带请求头Content-Type

app.use((req,res,next)=>{
    //针对跨域进行配置,允许任何源访问
    res.header('Access-Control-Allow-Origin', "*")
    // 允许前端请求中包含Content-Type这个请求头
    res.header('Access-Control-Allow-Headers', 'Content-Type')
    next()
})

经过这样配置,即可在服务端成功获取前端传递来的数据:

2.2、解决x-www-form-urlencoded内容格式

首先,我们再配置一个获取application/x-www-form-urlencoded内容格式的路由。之后通过配置app.use(bodyParser.urlencoded({extended: false}));即可

服务端代码如下:

// 创建应用对象
const express = require('express');
// 执行npm install body-parser之后再引入
const bodyParser = require('body-parser');
// 创建应用对象
const app = express();
// 处理application/json内容格式的请求体
app.use(bodyParser.json());
// 处理application/x-www-form-urlencoded内容格式的请求体
app.use(bodyParser.urlencoded({extended: false}));
app.use((req,res,next)=>{
    //针对跨域进行配置,允许任何源访问
    res.header('Access-Control-Allow-Origin', "*")
    // 允许前端请求中包含Content-Type这个请求头
    res.header('Access-Control-Allow-Headers', 'Content-Type')
    next()
})
// 创建路由规则
app.post("/login", (req,res) =>{
    // console.log(req);
    console.log("req.body:", req.body);
    res.send("login success")
})
app.post("/login2", (req,res) =>{
    // console.log(req);
    console.log(req.body);
    res.send("login2 success")
})
// 监听端口启动服务
app.listen(8002,() => {
    console.log("服务已启动,8002端口监听中...");
})

前端代码如下:添加了一个登录2按钮,同时绑定了它的请求方法。注意x-www-form-urlencoded这种请求的数据格式为:key=value&key=value

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="login">登录</button>
    <button id="login2">登录2</button>
    <script>
        let dom = document.getElementById("login")
        let dom2 = document.getElementById("login2")
        url = "http://localhost:8002/login"
        url2 = "http://localhost:8002/login2"
        dom.addEventListener("click",function(){
            // 创建XMLHttpRequest实例
            let xml = new XMLHttpRequest()
            // 请求体
            let data = {"username":"test","password":"123"}
            xml.onreadystatechange = function(){
                if(xml.readyState == 4){
                    console.log(xml.responseText);
                }
            }
            xml.open("post", url , true)
            xml.setRequestHeader("Content-Type","application/json");
            xml.send(JSON.stringify(data))
        })
        dom2.addEventListener("click",function(){
            // 创建XMLHttpRequest实例
            let xml = new XMLHttpRequest()
            xml.onreadystatechange = function(){
                if(xml.readyState == 4){
                    console.log(xml.responseText);
                }
            }
            xml.open("post", url2 , true)
            xml.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xml.send('username=test&password=123')
        })
    </script>
</body>
</html>

如下图所示:可见数据已经发送到后端。

同时,后端可以通过req.body成功获取到数据。

但是数据前面有一个Object: null prototype,这个是不影响取值的,按照上面这个例子,我们依旧可以通过req.body.usernamereq.body.password获取到对应的数据。

app.post("/login2", (req,res) =>{
    // console.log(req);
    console.log(req.body);
    console.log(req.body.username);
    console.log(req.body.password);
    res.send("login2 success")
})

当然,我们也可以通过先对对象进行JSON字符串转化JSON.stringify(),然后再转化成对象JSON.parse(),这样就可以将其去除了。

app.post("/login2", (req,res) =>{
    console.log(JSON.parse(JSON.stringify(req.body)));
    res.send("login2 success")
})

3、附

3.1、获取get请求参数

通过req.query来获取get请求参数

服务端代如下:我们再配置一个/data的路由。

// 创建路由规则
app.get('/data',(req,response) => {
    let obj = {
        name:'test',
        age:18
    }
    console.log(req.query);
    response.send(obj)
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="login">登录</button>
    <button id="login2">登录2</button>
    <button id="getinfo">获取数据</button>
    <script>
        let dom = document.getElementById("login")
        let dom2 = document.getElementById("login2")
        let dom3 = document.getElementById("getinfo")
        url = "http://localhost:8002/login"
        url2 = "http://localhost:8002/login2"
        // get请求中参数是放在url中
        url3 = "http://localhost:8002/data?id=3"
        dom.addEventListener("click",function(){
            // 创建XMLHttpRequest实例
            let xml = new XMLHttpRequest()
            // 请求体
            let data = {"username":"test","password":"123"}
            xml.onreadystatechange = function(){
                if(xml.readyState == 4){
                    console.log(xml.responseText);
                }
            }
            xml.open("post", url , true)
            xml.setRequestHeader("Content-Type","application/json");
            xml.send(JSON.stringify(data))
        })
        dom2.addEventListener("click",function(){
            // 创建XMLHttpRequest实例
            let xml = new XMLHttpRequest()
            xml.onreadystatechange = function(){
                if(xml.readyState == 4){
                    console.log(xml.responseText);
                }
            }
            xml.open("post", url2 , true)
            xml.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xml.send('username=test&password=123')
        })
        dom3.addEventListener("click",function(){
            // 创建XMLHttpRequest实例
            let xml = new XMLHttpRequest()
            xml.onreadystatechange = function(){
                if(xml.readyState == 4){
                    console.log(xml.responseText);
                }
            }
            xml.open("get", url3 , true)
            // get请求参数是放在url中,而不是通过xml.send()发送过去,不可以使用以下写法:xml.send("id=3")
            xml.send()
        })
        // console.log(a);
        // let a = 1
    </script>
</body>
</html>

成功通过req.query获取到get的请求参数

3.2、封装XMLHttpRequest

上面的请求代码太冗余,写了好多let xml = new XMLHttpRequest()、xml.open()、xml.send()等。我的本意是想着封装一下XMLHttpRequest,碰巧遇到了这个post参数取不到的问题。现在回到最开始,对XMLHttpRequest做一个简单的封装吧。

ajax.js代码如下:

(function () {
    const AJAX = function (options) {
        try {
            // 1、解析参数
            var method = options.method
            var url = options.url
            var data = options.data
            var contentType = options.contentType || "json"
            var headers = options.headers
            var async = options.async || false
            var successCallback = options.successCallback || function () { }
            var errorCallback = options.errorCallback || function (err) { console.log(err); }
        } catch (err) {
            console.log("Parsing parameter error")
        }
        try {
            // 2、创建XMLHttpRequest或ActiveXObject对象
            var xhr = null
            if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest()
            } else {
                // 兼容IE6, IE5
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            // 3、设置get请求参数
            if (method == "get") {
                var params = ""
                if (data) {
                    for (v in data) {
                        params += v + "=" + data[v] + "&"
                    }
                    params = params.replace(/&$/, "");
                    xhr.open(method, url + "?" + params, async)
                    xhr.send()
                } else {
                    xhr.open(method, url, async)
                    xhr.send()
                }
            } else if (method == "post") {
                // 设置post请求参数
                xhr.open(method, url, async)
                if (contentType == "application/x-www-form-urlencoded; charset=UTF-8") {
                    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                } else if (contentType == "application/json") {
                    xhr.setRequestHeader("Content-Type", "application/json");
                }
                xhr.send(JSON.stringify(data))
            }
            // 设置请求头
            if (headers) {
                for (h in headers) {
                    if (h == "Content-Type") {
                        continue
                    }
                    xhr.setRequestHeader(h, headers.h)
                }
            }
            xhr.onreadystatechange = function () {
                // 成功回调
                if (xhr.readyState == 4 && xhr.status == 200) {
                    successCallback()
                }
            }
            xhr.onerror = function (err) {
                // 失败回调
                errorCallback(err);
            }
            return xhr.response
        } catch (err) {
            console.log("Request Error");
        }
    }
    // 将AJAX对象暴露到window对象上
    window.AJAX = AJAX
})(window)

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../ajax.js"></script>
</head>
<body>
    <button id="login">登录</button>
    <button id="login2">登录2</button>
    <button id="getinfo">获取数据</button>
    <script>
        let dom = document.getElementById("login")
        let dom2 = document.getElementById("login2")
        let dom3 = document.getElementById("getinfo")
        url = "http://localhost:8002/login"
        url2 = "http://localhost:8002/login2"
        url3 = "http://localhost:8002/data?id=3"
        dom.addEventListener("click",function(){
            let options = {
                method:"post",
                url:"http://localhost:8002/login",
                data:{"username":"test","password":"123"},
                contentType:"application/json"
            }
            let res = AJAX(options)
            console.log("res", res);
        })
        dom2.addEventListener("click",function(){
            let options = {
                method:"post",
                url:"http://localhost:8002/login2",
                data:{"username":"test","password":"123"},
                contentType:"application/x-www-form-urlencoded; charset=UTF-8"
            }
            let res = AJAX(options)
            console.log("res", res);
        })
        dom3.addEventListener("click",function(){
            let options = {
                method:"get",
                url:"http://localhost:8002/data",
                data:{"id": 1}
            }
            let res = AJAX(options)
            console.log("res", res);
        })
    </script>
</body>
</html>

4、总结

首先分析了req.body获取不到数据的原因,之后给出了解决办法,通过设置响应头、使用中间件、配置跨域请求这三种方式来解决获取不到数据的问题。最后简单的封装了XMLHttpRequest

以上就是Express无法通过req.body获取请求传递的数据解决方法的详细内容,更多关于Express req.body请求传递的资料请关注我们其它相关文章!

(0)

相关推荐

  • 基于Express框架使用POST传递Form数据

    本文实例为大家分享了基于Express框架使用POST传递Form数据的具体代码,供大家参考,具体内容如下 客户端使用Form发送数据 在客户端Html文件中Form代码如下: <!-- POST test --> <form action="/test" method="post" id="foo" > <input type="text" name="username"&g

  • nodeJS express路由学习req.body与req.query方法实例详解

    目录 引言 前端路由 后端路由 Express路由教学 GET/POST路由演示 详解req处理数据的方法 引言 所谓 路由 就是根据不同的 url 地址展示不同的内容或页面 形象点 举个栗子: 电话的拨号界面咱们都见过都使用过 你输入一串号码,就可以拨号给指定的联系人 路由也是这个道理,你请求不同的 url 地址,服务器给你展示不同的内容或页面. 假如我们有一台提供 Web 服务的服务器的网络地址是192.168.1.66:8080 然后我们的服务器下挂载有如下一个资源 192.168.1.6

  • 轻量级数据库SQL Server Express LocalDb介绍

    目录 一.介绍 1.SqlLocalDb 2.轻量级数据库对比(LocalDB vs. SQL Express vs. Compact) 二.安装这个SqlLocalDb 1.通过VS Installer安装: 2.通过SQL Server Express安装 三.连接SqlLocalDB 1.SSMS可以连接此实例. 2.VS连接到SQLLoalDB 3.编写程序对已有数据的读取 四.SQL 示例数据库下载 一.介绍 1.SqlLocalDb 全称:SQL Server Express Loc

  • nodejs+express最简易的连接数据库的方法

    环境搭建 1.首先需要自行安装node环境 2.然后全局安装 express npm install -g express 3.创建express项目文件夹 express创建项目默认为jade模板引擎,若使用其他引擎,使用命令切换 express node_demo -e (选择ejs模板) // 在项目名称的后面添加 -e 那么创建出来的模板文件就是.ejs类型,语法是与html相同的 在vscode中打开我们建好的项目,目录如下: 对于ejs看着不习惯的同学可以将其改为html,如下: 然

  • 浅谈Express.js解析Post数据类型的正确姿势

    一.概念介绍 1.POST请求:HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据. 2. Content-Type : 是指 http/https 发送信息至服务器时的内容编码类型, Content-Type 用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据.四种常见的 POST 请求的 Content-Type 数据

  • node基于express框架操作Mysql数据库的步骤

    目录 一.在express项目中操作数据库的步骤 1.安装mysql模块 2.配置mysql模块 3.测试mysql模块能否正常工作 4.查询数据库数据 5.向数据库插入数据 6.更新数据库数据 7.更新数据库数据 8.删除数据库信息的标记删除 一.在express项目中操作数据库的步骤 ①安装操作 MySQL 数据库的第三方模块(mysql) ②通过mysql模块连接到MySQL 数据库 ③通过 mysql模块执行SQL语句 1.安装mysql模块 mysql模块是托管于npm 上的第三方模块

  • Express无法通过req.body获取请求传递的数据解决方法

    目录 前言 1.问题描述 2. 解决办法 2.1 解决JSON内容格式 2.2.解决x-www-form-urlencoded内容格式 3.附 3.1.获取get请求参数 3.2.封装XMLHttpRequest 4.总结 前言 最近尝试重新封装XMLHttpRequest,在发post请求的时候,发现express通过req.body获取不到数据,req.body打印出来是一个空对象. 网上也试了网上各种办法,还是不成功,最后发现需要在XMLHttpRequest请求时设置一个请求头,来标识发

  • AngularJS出现$http异步后台无法获取请求参数问题的解决方法

    本文实例讲述了AngularJS出现$http异步后台无法获取请求参数问题的解决方法.分享给大家供大家参考,具体如下: angular在通过异步提交数据时使用了与jQuery不一样的请求头部和数据序列化方式,导致部分后台程序无法正常解析数据. 原理分析(网上的分析): 对于AJAX应用(使用XMLHttpRequests)来说,向服务器发起请求的传统方式是:获取一个XMLHttpRequest对象的引用.发起请求.读取响应.检查状态码,最后处理服务端的响应.整个过程示例如下: var xmlht

  • 基于express中路由规则及获取请求参数的方法

    express中常见的路由规则 主要使用的路由规则是get和post两种,即 var express = require('express'); var app = express(); app.get(); // get和post两种请求方式 app.post(); app.get()和app.post()的第一个参数为请求路径,第二个参数为处理请求的回调函数:回调函数有两个参数,分别为req和res,代表请求信息和响应信息. 获取请求路径和请求体中的各种参数 路径请求及对应获取请求路径的形式

  • Java Spring Controller 获取请求参数的几种方法详解

    Java Spring Controller 获取请求参数的几种方法  1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交.若"Content-Type"="application/x-www-form-urlencoded",可用post提交 url形式:http://localhost:8080/SSMDemo/demo/addUser1?username=lixiaoxi&password=1

  • python直接获取API传递回来的参数方法

    之前用python调用API存JSON的时候试用了很多方法,现在调用API直接获取参数的时候也是查了好多例子(毕竟我是一个初学者). 结果让我发现了,原来只用把之前写的方法中去掉传参即可. 白白浪费了一个多小时的时间. 下面就是获取API传递回来的参数方法: #coding=utf-8 import httplib import json import urllib try: conn = httplib.HTTPConnection("127.0.0.1",8090) except

  • Django Python 获取请求头信息Content-Range的方法

    request请求头信息的键会加上HTTP_转换成大写存到request.META中 因此你只需要 content_range = request.META['HTTP_CONTENT_RANGE'] 这样就可以获取到Content-Range的信息. django官网的解释: A standard Python dictionary containing all available HTTP headers. Available headers depend on the client and

  • .net core webapi通过中间件获取请求和响应内容的方法

    本文主要根据中间件来实现对.net core webapi中产生的请求和响应数据进行获取并存入日志文件中: 这里不详细介绍日志文件的使用.你可以自己接入NLog,log4net,Exceptionless等 创建接口记录的中间件 using Microliu.Core.Loggers; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Inter

  • Android中post请求传递json数据给服务端的实例

    在最近的项目中有个需求是这样的: 入参封装成JSON,EXAMPLE: { "uuid": "iamauuid", "clientType": "AND", "content": "{\"gender\":\"F\",\"name\":\"TTT\"}"} 其中content中是json的object,且要求

  • vue配置请求本地json数据的方法

    本篇文章主要介绍了vue配置请求本地json数据的方法,分享给大家,具体如下: 在build文件夹下找到webpack.dev.conf.js文件,在const portfinder = require('portfinder')后添加 const express = require('express') const app = express() const appData = require('../data.json') // 加载本地json文件 const seller = appDa

  • AngularJS $http post 传递参数数据的方法

    在cordova开发的时候使用到了$http的post方法,传递的参数服务端怎么都接收不到,搜索了下,发现使用AngularJS通过POST传递参数还是需要设置一些东西才可以! 1.不能直接使用params 例如: $http({ method: "POST", url: "http://192.168.2.2:8080/setId", params: { cellphoneId: "b373fed6be325f7"} }).success();

随机推荐