那我来详细讲解一下。
1. 前置知识
在开始手写Node静态资源服务器之前,需要掌握以下几个知识点:
- Node.js模块系统
- HTTP协议
- URL模块
- fs模块
如果你对以上内容还不太了解,可以先自学一下再来开始。
2. 创建一个Node项目
首先,我们需要创建一个Node.js的项目,在项目根目录下创建一个名为app.js
的文件。
接下来,我们需要在项目根目录下创建一个public
目录,用来存放静态资源,比如HTML、CSS、JavaScript文件等。
3. 实现HTTP服务器
在app.js
中,我们需要引入http
模块,用来创建HTTP服务器。具体代码如下:
const http = require('http');
const server = http.createServer((req, res) => {
// 处理HTTP请求
});
server.listen(3000, () => {
console.log('Server is running on port 3000');
});
在上面的代码中,我们创建了一个HTTP服务器,并监听在3000端口上。
接下来,我们需要在处理HTTP请求的回调函数中,读取对应的静态资源文件,并发送给客户端。
4. 处理HTTP请求
在处理HTTP请求的回调函数中,我们需要分别处理以下两种请求:
- 请求静态资源文件
- 请求页面
4.1 请求静态资源文件
当我们请求静态资源文件(比如HTML、CSS、JavaScript)时,我们需要读取对应的文件,并发送给客户端。
具体代码如下:
const http = require('http');
const fs = require('fs');
const path = require('path');
const server = http.createServer((req, res) => {
const filePath = path.join(__dirname, 'public', req.url);
fs.readFile(filePath, (err, data) => {
if (err) {
res.writeHead(404);
res.end('404 Not Found');
return;
}
res.writeHead(200);
res.end(data);
});
});
server.listen(3000, () => {
console.log('Server is running on port 3000');
});
在上面的代码中,我们使用path
模块拼接出静态资源文件的完整路径,然后使用fs
模块读取文件数据。如果读取文件出错,我们会返回404错误码;否则,我们向客户端发送200成功状态码和读取到的文件数据。
4.2 请求页面
当我们请求页面时,我们需要读取对应的HTML文件,并将其中的静态资源路径替换为绝对路径,然后发送给客户端。
具体代码如下:
const http = require('http');
const fs = require('fs');
const path = require('path');
const server = http.createServer((req, res) => {
if (req.url === '/') {
const filePath = path.join(__dirname, 'public', 'index.html');
fs.readFile(filePath, (err, data) => {
if (err) {
res.writeHead(404);
res.end('404 Not Found');
return;
}
data = data.toString().replace(/(href|src)="([^"]+)"/g, (match, p1, p2) => {
return `${p1}="${req.protocol}://${req.headers.host}/${p2}"`;
});
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(data);
});
} else {
const filePath = path.join(__dirname, 'public', req.url);
fs.readFile(filePath, (err, data) => {
if (err) {
res.writeHead(404);
res.end('404 Not Found');
return;
}
res.writeHead(200);
res.end(data);
});
}
});
server.listen(3000, () => {
console.log('Server is running on port 3000');
});
在上面的代码中,我们首先判断请求的URL是否为根目录(即请求的是主页)。如果是,则读取index.html
文件;否则,读取对应的静态资源文件。
读取index.html
文件后,我们使用正则表达式把其中的静态资源路径替换为绝对路径。这里涉及到了req.protocol
和req.headers.host
两个变量,分别表示请求的协议和主机名(比如http
和localhost:3000
)。最后,我们向客户端发送HTML文件数据,并设置Content-Type为text/html。
5. 示例
下面我们来看两个具体的示例。
5.1 示例1:请求静态资源文件
当我们请求http://localhost:3000/style.css
时,服务器会读取public/style.css
文件并返回给客户端。
5.2 示例2:请求页面
当我们请求http://localhost:3000/
时,服务器会读取public/index.html
文件,并把其中的静态资源路径替换为http://localhost:3000/
开头的绝对路径,然后返回给客户端。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:手写Node静态资源服务器的实现方法 - Python技术站