Redirecting using “pure” Node.js from inside a callback function

问题: The following is an MCVE of my server.js code: let fs = require('fs'); let http = require('http'); http.createServer((req, res) => { // Handles GET requests i...

问题:

The following is an MCVE of my server.js code:

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

And, I've two HTML files as mentioned inside the code.

index.html

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

I've used inline script to minimize traffic in my MCVE. For development purposes, I'll be using external scripts on my website

login.html

<h1>Login</h1>

Now, when I open http://localhost, index.html shows up nicely. As you've noticed that index.html is just a button. So, when I click on that button, Ajax request is fired successfully and everything works fine (no console errors) EXCEPT the fact that page does not redirects. I don't know what it going wrong or what else is missing.

I'm a beginner in Node.js and read about redirection in Nodejs - Redirect url and How to redirect user's browser URL to a different page in Nodejs?, I've searched a lot but couldn't get a hint on this. Thanks for your time!

Also, I'm aware about express, but I don't consider use of frameworks as they hide core concepts.


EDIT: When I try redirecting without the callback concept, then it works fine, as this video tells us.


回答1:

This is not an issue with node.js. It is just how browsers behave.

Ajax (XHR) does not trigger redirects in the browser. When browsers implemented XHR browser developers assumed you want control of the page refresh behaviour. Therefore they made sure XHR does not trigger any default action. All redirects will be silent and the resultant data of the redirect will be passed to your XHR object's onreadystatechange callback.

If you want redirects to trigger page refresh you can simply choose to not use XHR. Instead do a form submission:

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

If instead you want to use AJAX, you will need to do the redirect in the browser like I mentioned above:

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

Then handle that response in the browser:

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();'>

But this is crazy ugly and almost impossible to read. I'd suggest refactoring that HTML to something like this:

<!-- 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()">
  • 发表于 2018-12-28 03:14
  • 阅读 ( 255 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除