简体   繁体   中英

NodeJS: load html with res.write()

I'm new to Node so I'm trying to learn it. I'm trying to load a simple HTML file in Node but that gives me an error as HTML is not defined when I use res.write(html) I saw some examples where are similar to me so I would like to understand what is wrong here. I wrote this:

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

const hostname = '127.0.0.1';
const port = 3000;

fs.readFile('./index.html', (err, html) => {
    if(err){
        throw err;
    }
});

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-type', 'text/html');
    res.write(html);    
    res.end();
});

server.listen(port, hostname, () => {
    console.log('Server started on port ' + port);
});

Your problems is that html variable is not set in the scope that you are trying to use it.

Almost everything in javascript is async, and you need to handle and build your logic so that values that is returned from an async call can be used elsewhere in the program.

In your case the readFile is an async call that reads and returns the file -- unfortunately for you the callback where you receive the html has it's own scope, and is not available after you have completed the execution of that callback.

The canonical mandatory readthough of how to do that is found here: How do I return the response from an asynchronous call?

There are many good solutions on this problem, for example using structures of closure or promises as well as other solutions.

A direct solution is to combine the and make use of the callback structure -- like in your example to make the user of html variable happen within the scope of the callback from the readFile , like

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-type', 'text/html');
    fs.readFile('./index.html', (err, html) => {
        if(err)
           res.write("Error");    
        else
           res.write(html);    
        res.end();
    });
});

As Soren pointed out, html is not defined when you call to res.write() . Asynchronous can be very convenient but it's a bit difficult to understand when you are a beginner. The best for you is to try to handle the concept of asynchronous tasks. Until then, a solution to your problem would be to use the synchronous version of fs.readFile , fs.readFileSync (docs here ), and call it inside the createServer function.

Since readFileSync returns the read stuff synchronously, you could do:

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-type', 'text/html');
    var html = fs.readFileSync('./index.html');
    res.write(html);    
    res.end();
});

Another option, as I guess you were trying to make, is to initialize the html variable in the callback of readFile .

var html_g; //global html variable
fs.readFile('./index.html', (err, html) => {
    if(err){
        throw err;
    } else {
        html_g = html; //html_g = content_of_index_file;
});

But since this function is asynchrounous, the createServer function could be called before html_g was initialize, causing problems.

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

const hostname = '127.0.0.1';
const port = 3000;

fs.readFile('./index.html', (err, html) => {
    if(err){
        throw err;
    } else if(html){
    const server = http.createServer((req, res) => {
       res.statusCode = 200;
       res.setHeader('Content-type', 'text/html');
       res.write(html);    
       res.end();
    });
}
});


server.listen(port, hostname, () => {
    console.log('Server started on port ' + port);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM