欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Express無法通過req.body獲取請求傳遞的數(shù)據(jù)解決方法

 更新時間:2022年12月05日 10:57:45   作者:shallowdream  
這篇文章主要為大家介紹了Express無法通過req.body獲取請求傳遞的數(shù)據(jù)解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

最近嘗試重新封裝XMLHttpRequest,在發(fā)post請求的時候,發(fā)現(xiàn)express通過req.body獲取不到數(shù)據(jù),req.body打印出來是一個空對象。

網(wǎng)上也試了網(wǎng)上各種辦法,還是不成功,最后發(fā)現(xiàn)需要在XMLHttpRequest請求時設(shè)置一個請求頭,來標(biāo)識發(fā)送過去數(shù)據(jù)的類型。

1、問題描述

服務(wù)端代碼如下:創(chuàng)建了一個/login請求,在控制臺輸出請求數(shù)據(jù)。

// 創(chuàng)建應(yīng)用對象
const express = require('express');
const bodyParser = require('body-parser');
// 創(chuàng)建應(yīng)用對象
const app = express();
app.use((req,res,next)=>{
    //針對跨域進(jìn)行配置,允許任何源訪問
    res.header('Access-Control-Allow-Origin', "*")
    next()
})
// 創(chuàng)建路由規(guī)則
app.post("/login", (req,res) =>{
    // 輸出req.body
    console.log("req.body:", req.body);
    res.send("login success")
})
// 監(jiān)聽端口啟動服務(wù)
app.listen(8002,() => {
    console.log("服務(wù)已啟動,8002端口監(jiān)聽中...");
})

前端代碼如下:

<!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>

明明已經(jīng)通過xml.send(JSON.stringify(data))已經(jīng)將數(shù)據(jù)轉(zhuǎn)換成json格式傳到后端,我們可以打開network查看。

但是express中就是獲取不到{"username":"test","password":"123"},控制臺輸出了一個空對象。

2、 解決辦法

2.1 解決JSON內(nèi)容格式

查了網(wǎng)上的教程,可以通過引入中間件'body-parser':它是一個HTTP請求體解析中間件,它用于解析客戶端請求的body中的內(nèi)容,如application/x-www-form-urlencodedapplication/json這兩種常用的內(nèi)容格式。

配置后代碼如下:

// 創(chuàng)建應(yīng)用對象
const express = require('express');
// 執(zhí)行npm install body-parser之后再引入
const bodyParser = require('body-parser');
// 創(chuàng)建應(yīng)用對象
const app = express();
// 處理application/json內(nèi)容格式的請求體
app.use(bodyParser.json());
app.use((req,res,next)=>{
    //實(shí)驗(yàn)驗(yàn)證,只需要設(shè)置這一個就可以進(jìn)行g(shù)et請求
    res.header('Access-Control-Allow-Origin', "*")//配置8080端口跨域
    next()
})
// 創(chuàng)建路由規(guī)則
app.post("/login", (req,res) =>{
    // console.log(req);
    console.log("req.body:", req.body);
    res.send("login success")
})
// 監(jiān)聽端口啟動服務(wù)
app.listen(8002,() => {
    console.log("服務(wù)已啟動,8002端口監(jiān)聽中...");
})

但是依舊獲取不到?。?!

原因:在請求中,沒有設(shè)置請求頭,也就是沒有指明你傳遞的是什么格式的數(shù)據(jù),需要通過xml.setRequestHeader("Content-Type","application/json")或者通過xml.setRequestHeader("Content-Type","application/x-www-form-urlencoded");設(shè)置請求頭中Content-Type值。

前端請求中補(bǔ)充xml.setRequestHeader("Content-Type","application/json")

xml.open("post", url , true)
// 添加Content-Type這個請求頭
xml.setRequestHeader("Content-Type","application/json");
xml.send(JSON.stringify(data))

同時在服務(wù)端配置跨域請求允許的訪問頭,如果不配置res.header('Access-Control-Allow-Headers', 'Content-Type'),則會出現(xiàn)以下提示content-type is not allowed。

跨域配置,配置請求中可攜帶請求頭Content-Type

app.use((req,res,next)=>{
    //針對跨域進(jìn)行配置,允許任何源訪問
    res.header('Access-Control-Allow-Origin', "*")
    // 允許前端請求中包含Content-Type這個請求頭
    res.header('Access-Control-Allow-Headers', 'Content-Type')
    next()
})

經(jīng)過這樣配置,即可在服務(wù)端成功獲取前端傳遞來的數(shù)據(jù):

2.2、解決x-www-form-urlencoded內(nèi)容格式

首先,我們再配置一個獲取application/x-www-form-urlencoded內(nèi)容格式的路由。之后通過配置app.use(bodyParser.urlencoded({extended: false}));即可

服務(wù)端代碼如下:

// 創(chuàng)建應(yīng)用對象
const express = require('express');
// 執(zhí)行npm install body-parser之后再引入
const bodyParser = require('body-parser');
// 創(chuàng)建應(yīng)用對象
const app = express();
// 處理application/json內(nèi)容格式的請求體
app.use(bodyParser.json());
// 處理application/x-www-form-urlencoded內(nèi)容格式的請求體
app.use(bodyParser.urlencoded({extended: false}));
app.use((req,res,next)=>{
    //針對跨域進(jìn)行配置,允許任何源訪問
    res.header('Access-Control-Allow-Origin', "*")
    // 允許前端請求中包含Content-Type這個請求頭
    res.header('Access-Control-Allow-Headers', 'Content-Type')
    next()
})
// 創(chuàng)建路由規(guī)則
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")
})
// 監(jiān)聽端口啟動服務(wù)
app.listen(8002,() => {
    console.log("服務(wù)已啟動,8002端口監(jiān)聽中...");
})

前端代碼如下:添加了一個登錄2按鈕,同時綁定了它的請求方法。注意x-www-form-urlencoded這種請求的數(shù)據(jù)格式為: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(){
            // 創(chuàng)建XMLHttpRequest實(shí)例
            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(){
            // 創(chuàng)建XMLHttpRequest實(shí)例
            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>

如下圖所示:可見數(shù)據(jù)已經(jīng)發(fā)送到后端。

同時,后端可以通過req.body成功獲取到數(shù)據(jù)。

但是數(shù)據(jù)前面有一個Object: null prototype,這個是不影響取值的,按照上面這個例子,我們依舊可以通過req.body.usernamereq.body.password獲取到對應(yīng)的數(shù)據(jù)。

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")
})

當(dāng)然,我們也可以通過先對對象進(jìn)行JSON字符串轉(zhuǎn)化JSON.stringify(),然后再轉(zhuǎn)化成對象JSON.parse(),這樣就可以將其去除了。

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

3、附

3.1、獲取get請求參數(shù)

通過req.query來獲取get請求參數(shù)

服務(wù)端代如下:我們再配置一個/data的路由。

// 創(chuàng)建路由規(guī)則
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">獲取數(shù)據(jù)</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請求中參數(shù)是放在url中
        url3 = "http://localhost:8002/data?id=3"
        dom.addEventListener("click",function(){
            // 創(chuàng)建XMLHttpRequest實(shí)例
            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(){
            // 創(chuàng)建XMLHttpRequest實(shí)例
            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(){
            // 創(chuàng)建XMLHttpRequest實(shí)例
            let xml = new XMLHttpRequest()
            xml.onreadystatechange = function(){
                if(xml.readyState == 4){
                    console.log(xml.responseText);
                }
            }
            xml.open("get", url3 , true)
            // get請求參數(shù)是放在url中,而不是通過xml.send()發(fā)送過去,不可以使用以下寫法:xml.send("id=3")
            xml.send()
        }) 
        // console.log(a);
        // let a = 1
    </script>
</body>
</html>

成功通過req.query獲取到get的請求參數(shù)

3.2、封裝XMLHttpRequest

上面的請求代碼太冗余,寫了好多let xml = new XMLHttpRequest()、xml.open()、xml.send()等。我的本意是想著封裝一下XMLHttpRequest,碰巧遇到了這個post參數(shù)取不到的問題?,F(xiàn)在回到最開始,對XMLHttpRequest做一個簡單的封裝吧。

ajax.js代碼如下:

(function () {
    const AJAX = function (options) {
        try {
            // 1、解析參數(shù)
            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、創(chuàng)建XMLHttpRequest或ActiveXObject對象
            var xhr = null
            if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest()
            } else {
                // 兼容IE6, IE5 
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            // 3、設(shè)置get請求參數(shù)
            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") {
                // 設(shè)置post請求參數(shù)
                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))
            }
            // 設(shè)置請求頭
            if (headers) {
                for (h in headers) {
                    if (h == "Content-Type") {
                        continue
                    }
                    xhr.setRequestHeader(h, headers.h)
                }
            }
            xhr.onreadystatechange = function () {
                // 成功回調(diào)
                if (xhr.readyState == 4 && xhr.status == 200) {
                    successCallback()
                }
            }
            xhr.onerror = function (err) {
                // 失敗回調(diào)
                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">獲取數(shù)據(jù)</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、總結(jié)

首先分析了req.body獲取不到數(shù)據(jù)的原因,之后給出了解決辦法,通過設(shè)置響應(yīng)頭、使用中間件、配置跨域請求這三種方式來解決獲取不到數(shù)據(jù)的問題。最后簡單的封裝了XMLHttpRequest。

以上就是Express無法通過req.body獲取請求傳遞的數(shù)據(jù)解決方法的詳細(xì)內(nèi)容,更多關(guān)于Express req.body請求傳遞的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論