2017-07-08 231 views
-3

我是Node新手,所以我试图去学习它。我试图在Node中加载一个简单的HTML文件,但是这给了我一个错误,因为当我使用res.write(html)时HTML没有被定义。我看到了一些与我相似的例子,所以我想知道这里有什么问题。 我写了这个:NodeJS:使用res.write加载html()

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

回答

1

你的问题是,html变量没有在你试图使用它的范围设置。

几乎所有的javascript都是异步的,你需要处理和构建你的逻辑,以便从异步调用返回的值可以在程序中的其他地方使用。

在你的情况下,readFile是一个读取并返回文件的异步调用 - 不幸的是,你收到html的回调函数有它自己的作用域,并且在你完成该回调的执行后不可用。

如何做到这一点的规范强制性readthough在这里找到:How do I return the response from an asynchronous call?

有在这个问题上采用封闭的结构或许多很好的解决方案,例如承诺以及其他解决方案。

一个直接的解决方案是结合和利用回调结构 - 在你的例子一样,使html变量的用户从readFile回调的范围内发生的,就像

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

正如Soren指出的那样,当您致电res.write()时,html未定义。异步可以非常方便,但是当你是初学者时,有点难以理解。最适合你的是尝试处理异步任务的概念。在此之前,解决您的问题的方法是使用fs.readFile,fs.readFileSync(文档here)的同步版本,并在createServer函数中调用它。

由于readFileSync同步返回读取的东西,你可以这样做:

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

另一种选择,我猜你试图做,是初始化html变量的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; 
}); 

但由于这个功能 - 异步,该createServer函数可以调用之前html_g是初始化,导致问题。

+0

从readFile的回调中移动createServer不是更好吗?这样就没有同步操作,也没有全局变量 - 在Javascript中这两种都被认为是不好的。 – Soren

+0

对不起,延迟@Soren,是的,你说得对。正如我所说,最好的选择是处理“异步-y”的概念并使用回调函数,但是几个月前我处于OP状态,即使它们编程不良,使您的第一个实验工作也始终令人振奋。但是,是的,从良好做法的角度来看,您的proporsal将是最好的选择。 –