我无法使用更多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)
答案 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.static
,express.static
,connect
模块正确提供静态图像的示例,请参阅此答案(就像您在此处一样)和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
。
旁注
此选项仅用于学习目的。一旦掌握了它的工作原理和发生的情况就没有必要使用这种方法,因为当你这样做时,只需要使用众所周知的工具,以更简单的方式完成工作。