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')
})
相关推荐
@PHARAOH14 分钟前
HOW - 构建一个轻量前后端一体服务
前端·微服务·服务端
无限进步_25 分钟前
【C++】C++11的类功能增强与STL变化
java·前端·数据结构·c++·后端·算法
一只小小Java26 分钟前
Echarts单表多图实现
前端·javascript·echarts
dunky35 分钟前
Spring AI 深度解析:把 LLM 抽象成 Spring Bean 的底层逻辑
前端
星栈36 分钟前
Rust WASM 文件上传全链路:从浏览器到 S3,一个字节都不能少
前端·前端框架·开源
濮水大叔36 分钟前
告别 Django Admin!这个 NodeJS 全栈框架让你在 DTO 中直接配置 Table/Form 渲染
前端·typescript·node.js
JarvanMo37 分钟前
Flutter 3.44 & Dart 3.12重磅发布!这些新特性太香了
前端
竹林81837 分钟前
用Viem替换ethers.js:一次合约交互的"减负"实战,我总算把TypeScript类型搞明白了
前端·javascript
To_OC39 分钟前
一个让我懵了半小时的时钟 Bug,注重前端三权分立落地
前端·代码规范
归故里40 分钟前
harmony-next.skills 为 AI 而生!
前端·后端·github