Node.js中的动静分离

什么是动静分离?

动静分离是指将网站的静态资源(如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')
})
相关推荐
Spider_Man几秒前
“AI查用户”也能这么简单?手把手带你用Node.js+前端玩转DeepSeek!
javascript·人工智能·node.js
满分观察网友z1 分钟前
vue的<router-link>的to里面的query和params的区别
前端
小约翰仓鼠2 分钟前
vue3表格使用Switch 开关
前端·javascript·vue.js
JiangJiang4 分钟前
🔥 面试官:Webpack 为什么能热更新?你真讲得清吗?
前端·面试·webpack
anyup23 分钟前
快崩溃了!华为应用商店已经 4 次驳回我的应用上线
前端·华为·uni-app
Qian Xiaoo37 分钟前
前后端分离开发 和 前端工程化
前端
要加油哦~1 小时前
vue · 插槽 | $slots:访问所有命名插槽内容 | 插槽的使用:子组件和父组件如何书写?
java·前端·javascript
先做个垃圾出来………1 小时前
split方法
前端
前端Hardy2 小时前
HTML&CSS:3D图片切换效果
前端·javascript