web-dev-qa-db-fra.com

Redirection en utilisant "pur" Node.js depuis une fonction de rappel

Ce qui suit est un MCVE de mon code server.js:

let fs = require('fs');
let http = require('http');

http.createServer((req, res) => {
    // Handles GET requests
    if(req.method == 'GET') {
        let file = req.url == '/' ? './index.html': '/login.html'; // just an example
        fs.readFile(file, (err, data) => {
            res.writeHead(200, {'Content-Type': 'text/html'});
            res.end(data);
        });
    } 

    // Handles POST requests
    else {
        read(status => {
            if(status) {
                res.writeHead(302, {
                    'Location': 'http://localhost:8000/login.html',
                    'Content-Type': 'text/html'
                });
                res.end();
                console.log('Redirected!');
            }
        });
    }
}).listen(8000);

// In my actual script, the `read` function reads JSON files and sends data,
// so I've used the callback function
let read = callback => fs.readFile( './index.html', (err, data) => callback(true) );

Et, j'ai deux fichiers HTML comme mentionné dans le code.

index.html

<input type="submit" onclick='let xhr = new XMLHttpRequest(); xhr.open("POST", "http://localhost:8000"); xhr.send();'>

J'ai utilisé le script en ligne pour minimiser le trafic dans mon MCVE. Pour des raisons de développement, j'utiliserai des scripts externes sur mon site Web.

login.html

<h1>Login</h1>

Maintenant, quand j'ouvre http://localhost, index.html apparaît bien. Comme vous l'avez remarqué, index.html n'est qu'un bouton. Ainsi, lorsque je clique sur ce bouton, la requête Ajax est déclenchée avec succès et tout fonctionne correctement (aucune erreur de console) SAUF le fait que la page ne redirige pas. Je ne sais pas ce qui ne va pas ou ce qui manque.

Je suis débutant dans Node.js et je connais la redirection dans Nodejs - Redirect url et Comment rediriger l'URL du navigateur de l'utilisateur vers une autre page dans Nodejs? , j'ai beaucoup cherché, mais je n'ai rien pu comprendre. Merci pour votre temps!

De plus, je suis conscient de l'utilisation de l'express, mais je n'envisage pas l'utilisation de cadres car ils cachent des concepts de base.


EDIT: Lorsque j'essaie de rediriger sans le concept de rappel, alors cela fonctionne très bien, car cette vidéo nous l'indique.

11
rv7

Ce n'est pas un problème avec node.js. C'est juste comment les navigateurs se comportent.

Ajax (XHR) ne déclenche pas de redirections dans le navigateur. Lorsque les navigateurs ont été mis en œuvre, les développeurs de navigateur XHR ont supposé que vous souhaitiez contrôler le comportement d'actualisation de la page. Par conséquent, ils se sont assurés que XHR ne déclenche aucune action par défaut. Toutes les redirections seront silencieuses et les données résultantes de la redirection seront transmises au rappel onreadystatechange de votre objet XHR.

Si vous souhaitez que les redirections déclenchent l'actualisation de la page, vous pouvez simplement choisir de ne pas utiliser XHR. Faites plutôt une soumission de formulaire:

<!-- index.html -->
<form action="http://localhost:8000" method="post">
    <input type="submit">
</form>

Si vous préférez utiliser AJAX, vous devrez effectuer la redirection dans le navigateur, comme indiqué plus haut:

// server.js

// ...

http.createServer((req, res) => {

    // ...

    // Handles POST requests
    else {
        read(status => {
            if(status) {
                res.writeHead(200, {'Content-Type': 'application/json'});
                res.end(JSON.stringify({
                    your_response: 'here'
                }));
            }
        });
    }
}).listen(8000);

Puis gérez cette réponse dans le navigateur:

index.html

<input type="submit" onclick='let xhr = new XMLHttpRequest();xhr.addEventListener("load", function(){var response = JSON.parse(this.responseText);/* check response if you need it: */if (response.your_response === 'here') {window.location.href = 'http://localhost:8000/login.html';}});xhr.open("POST", "http://localhost:8000");xhr.send();'>

Mais c’est moche et presque impossible à lire. Je suggérerais de refactoriser ce code HTML en quelque chose comme ceci:

<!-- index.html -->

<script>
    function handleSubmit () {
      let xhr = new XMLHttpRequest();
      xhr.addEventListener("load", function(){
        var response = JSON.parse(this.responseText);

        /* check response if you need it: */
        if (response.your_response === 'here') {
          window.location.href = 'http://localhost:8000/login.html'; // REDIRECT!!
        }
      });
      xhr.open("POST", "http://localhost:8000");
      xhr.send();
    }
</script>

<input type="submit" onclick="handleSubmit()">
12
slebetman

Si vous utilisez une application Web de noeud js, vous devriez utiliser express, sauf si vous avez une compréhension interne de la version actuelle du noeud que vous utilisez. 

Express est simple et votre code ressemblerait à ceci (et à rediriger)

app.get('/index.html',function(req,res,next){
   res.redirect('/path/to/redirect/file')
}

lien: http://expressjs.com/fr/4x/api.html#res.redirect

0
MIchael Odumosu