无法在节点js中使用多个html文件

时间:2017-04-17 10:25:48

标签: node.js

我无法使用更多HTML文件。我想在index.html中添加2-3个HTML链接,我该怎么办?下面是我的代码,我使用了2个html pagelinks,一个css和一个js。

这是test.js档案:

var http = require('http'),
    fs = require('fs');

http.createServer(function (req, res) {

    if(req.url.indexOf('.html') != -1){ //req.url has the pathname, check if it conatins '.html'

      fs.readFile(__dirname + '/public/index.html', function (err, data) {
        if (err) console.log(err);
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(data);
        res.end();
      });

    }

    if(req.url.indexOf('.js') != -1){ //req.url has the pathname, check if it conatins '.js'

      fs.readFile(__dirname + '/public/js/bootstrap.min.js', function (err, data) {
        if (err) console.log(err);
        res.writeHead(200, {'Content-Type': 'text/javascript'});
        res.write(data);
        res.end();
      });

    }


    if(req.url.indexOf('.css') != -1){ //req.url has the pathname, check if it conatins '.css'

      fs.readFile(__dirname + '/public/css/bootstrap.min.css', function (err, data) {
        if (err) console.log(err);
        res.writeHead(200, {'Content-Type': 'text/css'});
        res.write(data);
        res.end();
      });

    }
    if(req.url.indexOf('.html') != -1){ //req.url has the pathname, check if it conatins '.js'

      fs.readFile(__dirname + '/public/hello.html', function (err, data) {
        if (err) console.log(err);
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(data);
        res.end();
      });

    }

}).listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');

我在加载服务器时在cmd中遇到此错误:

D:\Nodejs>node test.js
Server running at http://127.0.0.1:3000/
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: write after end
    at ServerResponse.OutgoingMessage.write (_http_outgoing.js:441:15)
    at D:\Nodejs\test.js:45:13
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:446:3)

2 个答案:

答案 0 :(得分:2)

您似乎正在尝试在Node中编写自己的静态文件服务器。有一个简单的解决方案,比如Express框架中的express.static中间件,你所做的就是这样:

准备解决方案

var path = require('path');
var express = require('express');
var app = express();

var dir = path.join(__dirname, 'public');

app.use(express.static(dir));

app.listen(3000, () => console.log('Listening on http://localhost:3000/'));

(这是整个计划)。

重新发明轮子

现在,如果你坚持要自己重新实现所有这些,请继续阅读。

代码中的一个错误是在您实际检查代码中的.html字符串时检查扩展名。例如。这样:

if(req.url.indexOf('.html') != -1)

会匹配/my.html.styles/style.css之类的文件。 如果要检查文件扩展名,请使用:

path.extname(file);

请参阅: https://nodejs.org/api/path.html

当它找到匹配项时也不会终止,因为您使用了普通的if而非else if块并且您不能使用早期{{1}在你的代码中。

另一个问题是您已经硬编码了文件的所有路径,并且使用该代码您将无法仅提供任何HTML或CSS代码。此外,您的代码将无法正确提供图像,或多种样式等。从头开始重写并尝试修复它实际上会更容易。

好例子

有关如何使用Express和return,Express不使用express.staticexpress.staticconnect模块正确提供静态图像的示例,请参阅此答案(就像您在此处一样)和http模块与原始TCP连接:

以下是仅使用net的文件服务器的完整示例,即您在此处尝试执行的操作:

http

这段代码要复杂得多,甚至不能正确地提供与明确支持的MIME类型不同的MIME类型的文件,这只能说明使用能够正确完成所有这些操作的模块会更好。

因此,最好使用正确的工具,如var path = require('path'); var http = require('http'); var fs = require('fs'); var dir = path.join(__dirname, 'public'); var mime = { html: 'text/html', txt: 'text/plain', css: 'text/css', gif: 'image/gif', jpg: 'image/jpeg', png: 'image/png', svg: 'image/svg+xml', js: 'application/javascript' }; var server = http.createServer((req, res) => { var reqpath = req.url.toString().split('?')[0]; if (req.method !== 'GET') { res.statusCode = 501; res.setHeader('Content-Type', 'text/plain'); return res.end('Method not implemented'); } var file = path.join(dir, reqpath.replace(/\/$/, '/index.html')); if (file.indexOf(dir + path.sep) !== 0) { res.statusCode = 403; res.setHeader('Content-Type', 'text/plain'); return res.end('Forbidden'); } var type = mime[path.extname(file).slice(1)] || 'text/plain'; var s = fs.createReadStream(file); s.on('open', () => { res.setHeader('Content-Type', type); s.pipe(res); }); s.on('error', () => { res.setHeader('Content-Type', 'text/plain'); res.statusCode = 404; res.end('Not found'); }); }); server.listen(3000, () => console.log('Listening on http://localhost:3000/')); 或任何其他经过良好测试的Node静态文件服务器,您将避免许多问题。

有关详细信息,请参阅:

答案 1 :(得分:-1)

这是由您的if声明引起的。你应该使用这样的东西

if(req.url == '/index.html'){
    // load index.html
}else if(req.url == '/hello.html'){
    // load hello.html
}else if ... // the rest for css and js

<小时/> 一些解释

  • 当您只检查请求网址的indexOf时,您将无法与index.html hello.html区分开来(两者都有.html ),所以你要检查的是文件本身。

  • 对于该错误,由于网址中的任何.html都与IF匹配,并且您没有使用if..else,因此它将同时输入两个,在请求中调用end一个IF,并试图在另一个write after end

旁注

此选项仅用于学习目的。一旦掌握了它的工作原理和发生的情况就没有必要使用这种方法,因为当你这样做时,只需要使用众所周知的工具,以更简单的方式完成工作。