首页 > 解决方案 > JSON 对象未从 XMLHttpRequest 发送以表达

问题描述

我正在尝试将 JSON 对象发送到快速服务器。这是我给客户的代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Express demo</title>
</head>
<body>
<button onclick="sendUrlEncoded()">Send an application/x-www-form-urlencoded POST request</button>
<button onclick="sendJson()">Send an application/json POST request</button>
<div id="response"></div>
<script>
function sendUrlEncoded() {
    var data = "text=stuff";
    var http = new XMLHttpRequest();
    http.open("POST", "http://127.0.0.1");
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.send(data);
}

function sendJson() {
    var data = {text:"stuff"};
    var http = new XMLHttpRequest();
    http.open("POST", "http://127.0.0.1");
    http.setRequestHeader("Content-Type", "application/json");
    http.send(JSON.stringify(data));
}

</script>
</body>
</html>

这是服务器:

var express = require("express");
var path = require("path");
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

app.use(function(req, res, next) {
    console.log("Received request");
    console.log(req.headers);
    console.log(req.body);
    next();
});

app.get("/", function(req, res) {
    console.log("GET request");
    res.sendFile(path.join(__dirname + "/index.html"));
});

app.post("*", function(req, res) {
    console.log("Received post request");
    res.status=200;
});

var server = app.listen(3001, function() {console.log("Listening on port 3001")});

在这个问题的原始版本中,sendJson() 以前是“sendPost()”。当客户端发送 GET 请求或 XMLHttpRequest 时,服务器总是会收到它。如果是 GET 请求或通过 sendUrlEncoded() 发送,则包含正文中的数据并成功调用 app.get() 函数。但是,使用 sendJson(),服务器仅在通用消息处理程序中获取请求。它不调用 app.get(),请求的正文是 {}。此外,标题并不完全符合我的预期:

{
  host: 'xx.xxx.xxx.xxx:3001',
  connection: 'keep-alive',
  accept: '*/*',
  'access-control-request-method': 'POST',
  'access-control-request-headers': 'content-type',
  origin: 'http://192.168.0.102:3001',
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
  'sec-fetch-mode': 'cors',
  referer: 'http://192.168.0.102:3001/',
  'accept-encoding': 'gzip, deflate',
  'accept-language': 'en-US,en;q=0.9'
}

注意:我把真实IP地址换成了上面的xx.xxx.xxx.xxx。如果你能提供帮助,我真的很感激!

标签: javascriptajaxexpress

解决方案


[编辑]您仍然需要在app.get端点之前删除中间件,因为它只会增加一些噪音,并且还需要通过将响应发送回用户来结束请求,否则服务器将挂起。在您之前的代码中,您仅将响应状态设置为 200,但没有以sendor结束响应end 问题,最重要的是由两个 post 请求中使用的通配符 * 引起的。只需为您的请求使用两个不同的端点。

见下文。

var express = require("express");
var app = express();
var bodyParser = require('body-parser');

// create application/json parser
// this will only handle application/json requests
// and will be passed to the route handler as middleware

var jsonParser = bodyParser.json()

// create application/x-www-form-urlencoded parser

var urlencodedParser = bodyParser.urlencoded({ extended: true })

// POST /urlencoded (fictitious endpoint) gets urlencoded bodies
// Test with your forms
app.post('/urlencoded', urlencodedParser, function (req, res) {
    res.send('welcome, ' + JSON.stringify(req.body))
})

// POST / gets JSON bodies
// Test with application/json

app.post('/', jsonParser, function (req, res) {
    console.log("Received post request for application/json type");
    console.log(req.body);
    res.send(JSON.stringify(req.body)).end();
})

app.listen(3001, function () {
    console.log("Listening on port 3001")
});

当我将请求更改为 时application/json,我们得到了预期的结果,在本例中是回显的请求正文。

在此处输入图像描述

和服务器日志:

Listening on port 3001
Received post request for application/json type
{ test: 'some stuff to show' }

您不能为您的请求设置两种不同的内容类型。所以你要么发送application/jsontype 要么发送x-www-form-urlencoded.

这就是你所追求的吗?


推荐阅读