簡體   English   中英

NodeJs:無法發送帶有正文參數的 POST 請求:在服務器上時未定義 req.body.param

[英]NodeJs: Can't send POST request with body parameters: undefined req.body.param when on server

我有這個server.js代碼:

const bodyParser = require('body-parser');
const cors = require('cors');
const morgan = require('morgan');


var express = require('express')
    , http = require('http')
    , https = require('https')
    , app = express();
app.use(morgan('combined'));
app.use(bodyParser.json());
app.use(cors());

http.createServer(app);
https.createServer({  }, app);

app.get('/', (req, res) => {
    res.json({message: "Home"})
});

app.get('/test', (req, res) => {
    res.json({message: "Testing..."})
});

app.post('/token', (req, res) => {
    var clientId = req.body.client_id;
    var clientSecret = req.body.client_secret;

    if (clientId === 'admin' && clientSecret === 'admin') {
        res.json({message: "Your token is 123456"});
    }
    else  {
        res.json({message: "Not allowed!"});
    }
})

app.listen(process.env.PORT || 8081);

這個client.js代碼:

const http = require("http");
const querystring = require("querystring");

function getTestHome()  {
    const options = {
        method: "GET",
    }
    const token_endpoint = "http://localhost:8081/";
    const token_request = http.request(token_endpoint, options);
    token_request.once("error", err => {throw err});
    token_request.once("response",
        (token_stream) =>
            getFromStream(token_stream));
    token_request.end();
}

function getTestToken()  {
    const  parameters = {
        "grant_type": "client_credentials",
        "client_id": "admin",
        "client_secret": "admin"
    };

    const post_data = querystring.stringify(parameters);
    const options = {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        method: "POST",
        body: post_data
    }
    const token_endpoint = "http://localhost:8081/token";
    const token_request = http.request(token_endpoint, options);
    token_request.once("error", err => {throw err});
    token_request.once("response",
        (token_stream) =>
            getFromStream(token_stream));
    token_request.write(post_data);
    token_request.end();
}

function getFromStream(stream)  {
    let body = "";
    stream.on("data", piece => body += piece);
    stream.on("end", () => console.log(body));
}

getTestHome();  //{"message":"Home"}
getTestToken();  //{"message":"Not allowed!"}

我正在嘗試向/ (不帶參數的 GET 請求)和/token (帶有正文 JSON 數據的 POST 請求)發送請求。

GET 請求順利通過,我得到了

{"message":"Home"}

信息。

然而,盡管我在 POST 請求中發送了正確的client_idclient_secret ,我還是得到了

{"message":"Not allowed!"}

回消息。

我嘗試在server.js上使用調試器,我可以看到req.body.client_idreq.body_client_secretundefined的:

在此處輸入圖像描述

我做錯了什么,我該如何解決?

正確的 output 應該是

{"message":"Home"}
{"message": "Your token is 123456"}

PS POST 請求在 Postman 中工作正常:

在此處輸入圖像描述

編輯

我想我明白了。

添加

app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies

server.js解決了它。

但我想知道是否有辦法僅在client.js中解決它? 如果我無法訪問服務器代碼?

正如您指向您的編輯, 您需要添加

app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies

這是因為在您的客戶端,您將數據發送為:

Content-type: application/x-www-form-urlencoded

這使得 express 需要額外的代碼行來獲取 req.body 的數據(因為數據是如何發送的)。

另一方面,當您通過 Postman 進行操作時,您將內容類型顯式設置為 JSON raw,這會將請求的 header 自動設置為:

Content-type: application/json

Postman 內容類型標頭

所以,你可以在客戶端做的就是:將內容類型設置為 application/json,並將數據作為 JSON 發送:

function getTestToken() {
    const parameters = {
        "grant_type": "client_credentials",
        "client_id": "admin",
        "client_secret": "admin"
    };

    const options = {
        headers: { 'Content-Type': 'application/json' },
        method: "POST",
    }
    const token_endpoint = "http://localhost:8081/token";
    const token_request = http.request(token_endpoint, options);
    token_request.once("error", err => { throw err });
    token_request.once("response",
        (token_stream) =>
        getFromStream(token_stream));
    token_request.write(JSON.stringify(parameters));
    token_request.end();
}

您可以在客戶端采用這種方法,而無需修改服務器的代碼。 使用這種方法,您還可以跳過查詢字符串模塊的導入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM