什么是动静分离?
动静分离是指将网站的静态资源(如HTML、CSS、JavaScript、图片、视频等)与动态内容(如通过数据库查询、用户提交表单等生成的内容)分离,并由不同的服务器或不同的服务进程来处理这两种类型的请求。这种分离可以显著提升网站的加载速度,因为静态资源通常可以缓存,并且不依赖于后端的实时计算。
Node.js中的动静分离实现
在Node.js中,动静分离的实现可以通过多种方式进行,包括但不限于使用反向代理服务器(如Nginx)、配置Express框架中间件,或者结合使用CDN(内容分发网络)服务。
下面是一个使用Node.js编写的示例代码,演示了如何处理动静分离的请求:
静态资源的处理
因为每个文件所对应的mime类型都不一样,如果手写的话有很多,不过强大的nodejs社区提供了mime库,可以帮我们通过后缀直接分析出 所对应的mime类型,然后我们通过强缓存让浏览器缓存静态资源
安装依赖
js
npm i mime
比如我在static目录有index.css、index.html、demo.png文件,这些都是静态资源
js
import http from 'http';
import fs from 'fs';
import path from 'path';
import mime from 'mime';
const server = http.createServer((req, res) => {
const { method, url } = req
if (method === 'GET' && url.startsWith('/static')) {
const staticPath = path.join(process.cwd(), url)
const type = mime.getType(staticPath)
fs.readFile(staticPath, (err, data) => {
if (err) {
res.writeHead(404, {
'Content-Type': 'text/plain;charset=utf-8'
})
res.end('404 Not Found')
} else {
res.writeHead(200, {
'Content-Type': type
})
res.end(data)
}
})
}
})
server.listen(3000, () => {
console.log('server is running at http://localhost:3000')
})
访问地址:http://localhost:3000/static/index.css ,可以看到index.css资源是能直接访问到的
并且content-type对应的类型也是text/css
访问地址:http://localhost:3000/static/demo.png ,可以看到demo.png是能直接访问到的,并且content-type对应的类型也是image/png
加缓存
js
import http from 'http';
import fs from 'fs';
import path from 'path';
import mime from 'mime';
const server = http.createServer((req, res) => {
// 解构请求对象以获取HTTP方法和URL
const { method, url } = req
// 检查请求是否为GET请求且URL以'/static'开头
if (method === 'GET' && url.startsWith('/static')) {
// 构造静态文件的完整路径
const staticPath = path.join(process.cwd(), url)
// 使用mime模块获取文件的MIME类型
const type = mime.getType(staticPath)
fs.readFile(staticPath, (err, data) => {
if (err) {
res.writeHead(404, {
'Content-Type': 'text/plain;charset=utf-8'
})
res.end('404 Not Found')
} else {
console.log('test');
res.writeHead(200, {
'Content-Type': type, // 设置响应的内容类型
'cache-control': 'public, max-age=3600' // 设置缓存控制头,允许缓存1小时
})
res.end(data)
}
})
}
})
server.listen(3000, () => {
console.log('server is running at http://localhost:3000')
})
第一次访问http://localhost:3000/static/demo.png , 控制台打印出test
再一次访问http://localhost:3000/static/demo.png , 控制台不会再打印出test,因为我们设置了缓存
动态资源的处理
js
import http from 'http';
import fs from 'fs';
import path from 'path';
import mime from 'mime';
const server = http.createServer((req, res) => {
// 解构请求对象以获取HTTP方法和URL
const { method, url } = req
// 处理静态资源
if (method === 'GET' && url.startsWith('/static')) {
// 其余代码
}
// 处理动态资源(随便定义的判断逻辑,根据需求合理定义)
if ((method === 'GET' || method === 'POST') && url.startsWith('/api')) {
// ...处理动态资源的逻辑
}
})
server.listen(3000, () => {
console.log('server is running at http://localhost:3000')
})