调用顺序中的NodeJS'express.use'不一致

时间:2019-01-26 14:37:58

标签: javascript html node.js

版本:express@4.16.4,body-parser@1.18.3

使用AWS EC2上的nodejs设置进行了测试,并且html网页直接在本地计算机上运行。我注意到中间件/路由器的调用顺序中存在不一致的行为。在以下html中,返回json {from:'nodejs'}的GET请求是可以的。但是,POST请求直接跳转到方法Invalid URL

更多测试场景:

  1. 完全删除第二个app.use,返回json {from:'nodejs'}的GET和POST请求都可以,并且POST请求req.body输出正确的数据{from:'html'}
  2. 返回json xhr.setRequestHeader("Content-Type", "application/json");都可以删除{from:'nodejs'}的GET和POST请求都可以,但是req.body为空白,这是预期的

html代码:

<!DOCTYPE html>
<html>
<body>

<button type="button" onclick="get()">GET</button>
<button type="button" onclick="post()">POST</button>
<p id="output"></p>

<script>
function get() {

    var xhr = new XMLHttpRequest();
    xhr.open("GET", 'http://54.169.54.221:8000/get', true);

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            var json = JSON.parse(xhr.responseText);
            console.log("Server Responded:" + JSON.stringify(json));
            document.getElementById("output").innerHTML = JSON.stringify(json);
        }
    };
    xhr.send();
}

function post() {

    var json = '{"from":"html"}';
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'http://54.169.54.221:8000/post', true);

    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            var json = JSON.parse(xhr.responseText);
            console.log("Server Responded:" + JSON.stringify(json));
            document.getElementById("output").innerHTML = JSON.stringify(json);
        }
    };
    xhr.send(json);
}
</script> 

</body>
</html> 

服务器代码:

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

app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(bodyParser.json());

app.use(function(req, res, next) {
    console.log( 'global pre-process middleware invoked' );
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'content-type');
    next();
});

app.get('/get', function (req, res, next) {
    try {
        var json = {from:'nodejs'};
        console.log( JSON.stringify(json,null,'    ') );
        res.end( JSON.stringify(json,null,'    ') );
    } catch (e) {
        next(e);
    }
});

app.post('/post', function (req, res, next) {
    try {
        console.log(JSON.stringify(req.body));

        var json = {from:'nodejs'};
        console.log( JSON.stringify(json,null,'    ') );
        res.end( JSON.stringify(json,null,'    ') );
    } catch (e) {
        next(e);
    }
});

app.use(function(req, res, next) {
    console.log('Invalid URL');
});

var server = app.listen(8000, function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log('Listening at http://%s:%s', host, port);
});

3 个答案:

答案 0 :(得分:0)

请更新服务器端代码,因为在客户端上您正在使用Content-type:application / json。

$strLiteData = /* from your zip file */

$dbFile = tmpfile();
$dbPath = stream_get_meta_data($dbFile)['uri'];

fwrite($dbFile, $strLiteData);

$pdo = new PDO('sqlite:' . $dbPath);

/*
 * do your PDO stuff here
 */

$strLiteData = file_get_contents($dbPath);

要解决此问题,请在节点服务器代码中同时指定内容类型。

xhr.setRequestHeader("Content-Type", "application/json");

结果,您的节点服务器文件将如下所示:

res.setHeader("Content-Type", "application/json")

答案 1 :(得分:0)

该错误是由于您未真正验证,而您的中间件功能中的验证URL所致

 app.use(function(req, res, next) {
   If(success with url) {
      next();
   } else {
      console.log('invalid url');
   }
 });

答案 2 :(得分:0)

这是CORS Access-Control-Allow-Origin的行为。浏览器在发送除Content-Type以外的POST请求之前的浏览器:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

发送一个OPTIONS请求,询问服务器是否可以接受这样的请求。在我的服务器代码中,未处理此OPTIONS请求,因此被'Invalid URL'

拦截

有关OPTIONS request and CORS的更多信息