为了提供静态资源,我们可以用@nestjs/serve-static包里的ServeStaticModule
服务器上的静态资源,一般指的是文件,比如图片、音频、视频、文本文件或者二进制文件等等。

或者是一些单页面应用程序(Single Page Application, SPA)。从服务器上请求得到网页,然后网页再执行自己的业务。

安装

首先我们需要安装@nestjs/serve-static包。
在工程路径下

1
$ npm install --save @nestjs/serve-static

安装完成后,工程的package.json里会多出

1
2
3
"dependencies": {
"@nestjs/serve-static": "^2.1.4",
}

使用

在root AppModule中,引入ServeStaticModule模块。

1
2
3
4
5
6
7
8
9
10
import { ServeStaticModule } from '@nestjs/serve-static';

@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'rustfisherData'),
exclude: ['/api*'],
}),],
})
export class AppModule { }

imports里添加了ServeStaticModule模块。需要用到ServeStaticModule.forRoot方法。

  • rootPath 指定了静态文件的根目录
  • exclude 表明排除在外的文件和目录

路径说明

我们关心的是,服务器上哪个目录可以让客户端访问,哪个目录是不开放的。

__dirname 获取到的是当前目录的路径。
使用join()方法,拼接出一个新的路径。

工程编译出来的文件放在dist目录中。app.module.js文件也在里面。
此时__dirname表示的是dist目录的路径。
那么join(__dirname, '..', 'rustfisherData')得到的路径就是与dist目录同级的rustfisherData

假设我们服务器上运行目录是/home/rustfisher/server/rf-server-nest/dist
那么静态文件存放的目录就是/home/rustfisher/server/rf-server-nest/rustfisherData

配置

ServeStaticModule提供了丰富的自定义控制。开发者可以自定义它的行为。
比如像前面那样设置静态文件根目录rootPath;设置排除的路径exclude

GitHub上有详细配置

注意
访问目录时,默认会找index.html文件发送回去。后文会有更多说明。

客户端访问

假设服务部署好了(并不是真实项目),网址是 https://rustfisher.com 。部署好服务后,我们测试一下。

打开浏览器,访问url: https://rustfisher.com/some/path/to/img/11.jpg
可以在网页上看到图片(并不是真实项目)。

如果访问一个不存在的路径(文件),它会返回一个默认的index.html。如果没有这个文件,则会报一个ENOENT错误信息

1
2
[Nest] 32378   - 07/10/2021, 8:15:00 PM   [ExceptionsHandler] ENOENT: no such file or directory, 
stat '/home/rustfisher/server/rf-server-nest/rustfisherData/index.html' +234539ms

不想让它报这个错,我们可以自己弄一个index.html文件放到对应路径上。
这样做的话,访问目录或者不存在的文件会默认返回index.html文件。

小结

提供访问静态文件的功能比较常见。客户端使用一个url,就能访问服务器上的文件。
现在很常见的做法是把文件放在CDN上,减轻服务器的io压力和网络压力。
在Linux服务器上,nginx和同类的服务也能轻松实现类似的提供静态文件的功能。