如何设置一个 nodejs 服务器,通过检查 url 为客户端提供正确的文件?
How do I set up a nodejs server that gives the client the correct file by checking the url?
我正在尝试编写一个节点 js 服务器,如果资源在文件系统中,它会返回用户请求的任何内容。
例如,如果请求 URL 是 /index.html
,它会尝试在根目录中找到一个名为 'index.html' 的文件,并使用对该文件的流进行响应。如果请求是 /myscript.js
,它会做同样的事情,找到一个名为 myscript.js
的文件并将其通过管道传递给响应。
这是我目前的情况:
var http = require("http");
var fs = require("fs");
var port = process.env.PORT || 3000;
http.createServer(function (request, response) {
if (request.method == "GET") {
console.log(request.url);
if (request.url == "/") { // if the url is "/", respond with the home page
response.writeHead(200, {"Content-Type": "text/html"});
fs.createReadStream("index.html").pipe(response);
} else if (fs.existsSync("." + request.url)) {
response.writeHead(200/*, {"Content-Type": request.headers['content-type']}*/);
fs.createReadStream("." + request.url).pipe(response);
} else {
response.writeHead(404, {"Content-Type": "text/plain"});
response.end("404 Not Found");
}
} else {
response.writeHead(404, {"Content-Type": "text/plain"});
response.end("404 Not Found");
}
}).listen(port);
// Console will print the message
console.log('Server running at http://127.0.0.1:' + port +'/');
这段代码有几点我不喜欢:
- 显然
fs
认为只要路径以/
开头,文件就不存在,所以我必须在文件路径前加一个.
。参见第 10 和 12 行。这会一直有效吗?我觉得这是一个非常糟糕的解决问题的方法。
- 我不知道所请求文件的内容类型(第 11 行)。我在网上搜索并找到了很多方法来处理我必须使用 npm 安装的其他模块。节点中有什么东西可以确定内容类型吗?
解决你的两个要点:
- 使用
fs
时需要 .
是有道理的,因为 fs
否则会查看系统的根目录。请记住,系统根目录不同于您的服务器根目录。
- 一个想法是使用
path.extname
,然后使用 switch
语句来设置内容类型。
下面的代码摘自 blog post 我写的关于如何使用没有 Express 的 Node 设置一个简单的静态服务器:
let filePath = `.${request.url}`; // ./path/to/file.ext
let ext = path.extname(filePath); // .ext
let contentType = 'application/octet-stream'; // default content type
if(ext === '') {
filePath = './index.html'; // serve index.html
ext = '.html';
}
switch (ext) {
case '.html':
contentType = 'text/html';
break;
case '.css':
contentType = 'text/css';
break;
case 'js':
contentType = 'text/javascript';
}
我正在尝试编写一个节点 js 服务器,如果资源在文件系统中,它会返回用户请求的任何内容。
例如,如果请求 URL 是 /index.html
,它会尝试在根目录中找到一个名为 'index.html' 的文件,并使用对该文件的流进行响应。如果请求是 /myscript.js
,它会做同样的事情,找到一个名为 myscript.js
的文件并将其通过管道传递给响应。
这是我目前的情况:
var http = require("http");
var fs = require("fs");
var port = process.env.PORT || 3000;
http.createServer(function (request, response) {
if (request.method == "GET") {
console.log(request.url);
if (request.url == "/") { // if the url is "/", respond with the home page
response.writeHead(200, {"Content-Type": "text/html"});
fs.createReadStream("index.html").pipe(response);
} else if (fs.existsSync("." + request.url)) {
response.writeHead(200/*, {"Content-Type": request.headers['content-type']}*/);
fs.createReadStream("." + request.url).pipe(response);
} else {
response.writeHead(404, {"Content-Type": "text/plain"});
response.end("404 Not Found");
}
} else {
response.writeHead(404, {"Content-Type": "text/plain"});
response.end("404 Not Found");
}
}).listen(port);
// Console will print the message
console.log('Server running at http://127.0.0.1:' + port +'/');
这段代码有几点我不喜欢:
- 显然
fs
认为只要路径以/
开头,文件就不存在,所以我必须在文件路径前加一个.
。参见第 10 和 12 行。这会一直有效吗?我觉得这是一个非常糟糕的解决问题的方法。 - 我不知道所请求文件的内容类型(第 11 行)。我在网上搜索并找到了很多方法来处理我必须使用 npm 安装的其他模块。节点中有什么东西可以确定内容类型吗?
解决你的两个要点:
- 使用
fs
时需要.
是有道理的,因为fs
否则会查看系统的根目录。请记住,系统根目录不同于您的服务器根目录。 - 一个想法是使用
path.extname
,然后使用switch
语句来设置内容类型。
下面的代码摘自 blog post 我写的关于如何使用没有 Express 的 Node 设置一个简单的静态服务器:
let filePath = `.${request.url}`; // ./path/to/file.ext
let ext = path.extname(filePath); // .ext
let contentType = 'application/octet-stream'; // default content type
if(ext === '') {
filePath = './index.html'; // serve index.html
ext = '.html';
}
switch (ext) {
case '.html':
contentType = 'text/html';
break;
case '.css':
contentType = 'text/css';
break;
case 'js':
contentType = 'text/javascript';
}