我有这个 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_id
和 client_secret
,我还是得到了
{"message":"Not allowed!"}
回消息。
我尝试在 server.js 上使用调试器,我可以看到 req.body.client_id
和 req.body_client_secret
是 undefined
:
我做错了什么,我该如何解决?
正确的输出应该是
{"message":"Home"}
{"message": "Your token is 123456"}
PS POST 请求在 Postman 中工作正常:
编辑:
我想我明白了。
添加
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
到 server.js 解决了它。
但我想知道是否有办法仅在 client.js 中解决它?如果我无法访问服务器代码?
答案 0 :(得分:1)
就在您指向您的编辑时,you needed to add:
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
这是因为在您的客户端,您将数据发送为:
Content-type: application/x-www-form-urlencoded
这使得 express 需要额外的代码行来获取 req.body 中的数据(因为数据是如何发送的)。
另一方面,当您通过 Postman 进行操作时,您将内容类型显式设置为 JSON 原始数据,从而自动将请求标头设置为:
Content-type: application/json
因此,您可以在客户端做的就是:将内容类型设置为 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();
}
您可以在客户端采用这种方法,而无需修改服务器的代码。使用这种方法,您还可以跳过查询字符串模块的导入。