Version: express@4.16.4, body-parser@1.18.3

Testé avec la configuration de nodejs sur AWS EC2 et une page Web html exécutée directement sur la machine locale. Je remarque qu'il y a un comportement incohérent dans la séquence d'appel du middleware / routeur. En html suivant, la requête GET est ok retournant json {from:'nodejs'}. Cependant, la requête POST passe directement à la méthode Invalid URL.

Plus de scénarios de test:

  1. Supprimez entièrement la deuxième app.use les requêtes GET et POST sont correctes renvoyant json {from:'nodejs'}, et la requête POST req.body génère les données correctes {from:'html'}
  2. La suppression de xhr.setRequestHeader("Content-Type", "application/json"); les requêtes GET et POST permet de renvoyer json {from:'nodejs'}, mais req.body est vide, ce qui est attendu

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

Code serveur:

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

0
Konsy 26 janv. 2019 à 17:37

3 réponses

Meilleure réponse

C'est le comportement de CORS Access-Control-Allow-Origin. Le navigateur avant d'envoyer une demande POST avec un type de contenu autre que:

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

Envoie une requête OPTIONS, demandant si le serveur peut accepter une telle requête. Dans mon code serveur, cette demande OPTIONS n'est pas traitée, donc, interceptée par 'Invalid URL'

Plus d'informations sur la requête OPTIONS et CORS

0
Konsy 29 janv. 2019 à 01:45

Veuillez mettre à jour le code côté serveur car côté client, vous utilisez Content-type: application / json.

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

Pour résoudre ce problème, veuillez également spécifier le type de contenu dans le code du serveur de noeud.

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

En conséquence, votre fichier de serveur de noeud ressemblera à ceci

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

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("Content-Type", "application/json")
    next();
});

app.post('/echo', function (req, res, next) {
    try {
        var body = JSON.stringify(req.body);
        console.log('/echo: ' + body);
        res.send(body);
    } catch (e) {
        next(e);
    }
});

app.use(function(req, res) {
    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);
});

0
Mubeen Khan 26 janv. 2019 à 16:25

L'erreur est due au fait que vous n'avez pas vraiment validé, quoi que ce soit dans votre URL de validation dans votre fonction middleware

 app.use(function(req, res, next) {
   If(success with url) {
      next();
   } else {
      console.log('invalid url');
   }
 });
0
elraphty 26 janv. 2019 à 16:44