您现在的位置是:网站首页 > 静态文件服务与资源托管文章详情

静态文件服务与资源托管

静态文件服务与资源托管

Express框架内置了express.static中间件,专门用于托管静态文件。通过简单配置就能让服务器提供图片、CSS、JavaScript等静态资源。静态文件服务是Web应用的基础功能,直接影响页面加载速度和用户体验。

基本使用方法

在Express应用中启用静态文件服务只需要一行代码:

const express = require('express');
const app = express();

// 托管public目录下的静态文件
app.use(express.static('public'));

这行代码会让Express自动处理public目录下的所有静态文件请求。例如:

  • public/images/logo.png 可以通过 /images/logo.png 访问
  • public/css/style.css 可以通过 /css/style.css 访问

虚拟路径前缀

有时需要为静态文件添加路径前缀,避免与其他路由冲突:

app.use('/static', express.static('public'));

这样配置后:

  • public/images/logo.png 需要通过 /static/images/logo.png 访问
  • public/js/app.js 需要通过 /static/js/app.js 访问

多静态目录托管

一个应用可以同时托管多个静态文件目录:

app.use(express.static('public'));
app.use(express.static('files'));

Express会按照中间件注册顺序查找文件。如果publicfiles目录都有style.css文件,会优先返回public目录下的版本。

缓存控制

静态文件通常需要设置缓存策略提升性能:

app.use(express.static('public', {
  maxAge: '1d',
  etag: false
}));

可选配置项包括:

  • maxAge: 设置Cache-Control头的max-age值(如'1d'表示1天)
  • etag: 是否启用ETag验证(默认true)
  • lastModified: 是否发送Last-Modified头(默认true)
  • setHeaders: 自定义设置响应头

安全考虑

托管静态文件时需要注意安全问题:

app.use('/static', express.static('public', {
  dotfiles: 'ignore',  // 忽略点文件
  index: false,        // 禁用目录索引
  redirect: false      // 禁用路径重定向
}));

特别要注意:

  • 不要直接托管项目根目录
  • 禁用目录列表功能
  • 限制访问特定文件类型

高级自定义处理

通过setHeaders可以实现更精细的控制:

app.use('/assets', express.static('public', {
  setHeaders: (res, path) => {
    if (path.endsWith('.wasm')) {
      res.set('Content-Type', 'application/wasm');
    }
  }
}));

这个例子特别设置了.wasm文件的MIME类型,确保WebAssembly文件能正确加载。

与其他中间件配合

静态文件中间件可以与其他中间件组合使用:

const compression = require('compression');

app.use(compression());
app.use(express.static('public'));

这样配置会先压缩静态文件再发送,显著减少传输数据量。注意压缩中间件应该放在静态中间件之前。

生产环境优化

生产环境中通常需要反向代理(如Nginx)来处理静态文件,但Express仍然可以做一些优化:

const oneDay = 86400000;

app.use(express.static('public', {
  maxAge: oneDay,
  immutable: true,
  cacheControl: true,
  lastModified: false
}));

这种配置适合版本化的静态资源(如带hash的文件名),设置长期缓存提升性能。

动态文件与静态文件结合

有时需要根据条件返回不同静态文件:

app.use('/themes/:theme', (req, res, next) => {
  const theme = req.params.theme;
  express.static(`public/themes/${theme}`)(req, res, next);
});

这种模式可以实现动态切换主题样式,同时保持静态文件的高效服务。

文件上传与下载

虽然主要是静态文件服务,但有时也需要处理文件传输:

const path = require('path');
const fs = require('fs');

app.get('/download/:file', (req, res) => {
  const file = path.join(__dirname, 'uploads', req.params.file);
  res.download(file);  // 触发文件下载
});

res.download()方法会自动设置合适的头信息并处理文件流。

性能监控

可以添加中间件监控静态文件服务性能:

app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    console.log(`${req.method} ${req.url} - ${Date.now() - start}ms`);
  });
  next();
});

app.use(express.static('public'));

这样能记录每个静态文件请求的处理时间,帮助识别性能瓶颈。

跨域资源共享(CORS)

静态资源可能需要配置CORS:

app.use('/cdn', express.static('public', {
  setHeaders: (res) => {
    res.set('Access-Control-Allow-Origin', '*');
  }
}));

这对CDN托管或跨域资源特别重要,确保浏览器能正确加载资源。

条件请求处理

Express静态中间件默认支持条件请求(基于ETag和Last-Modified):

app.use(express.static('public', {
  etag: true,          // 默认启用
  lastModified: true   // 默认启用
}));

当客户端发送If-None-Match或If-Modified-Since头时,中间件会返回304状态码减少传输。

自定义404处理

静态文件不存在时的默认行为是继续到下一个中间件,可以自定义处理:

app.use('/static', express.static('public'));

// 静态文件404处理
app.use('/static', (req, res) => {
  res.status(404).send('File not found');
});

这种模式先尝试静态文件,不存在时返回自定义404响应而不是继续路由。

静态文件与SPA结合

单页应用(SPA)通常需要特殊处理:

// 静态文件
app.use(express.static('public'));

// 所有其他请求返回index.html
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

这样配置既支持静态资源请求,又让前端路由能正确处理各种URL。

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步