You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular传图至NestJS存DB后本地无法显示,路径异常求助

问题:Angular上传图片到NestJS后端后无法本地显示图片

已按NestJS官方Multer文档实现Angular前端上传图片到NestJS后端,图片已成功保存到文件系统和数据库,但本地显示图片时无法获取正确路径。相关代码如下:

NestJS 后端代码

使用FileInterceptor实现文件上传:

import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';

// 文件存储配置
export const storage = {
  storage: diskStorage({
    destination: './files',
    filename: (req, file, callback) => {
      const uniqueSuffix: string =
        Date.now() + '-' + Math.round(Math.random() * 1e9);
      const ext = extname(file.originalname);
      const filename = `${uniqueSuffix}${ext}`;
      callback(null, filename);
    },
  }),
};

@Post('upload')
@UseInterceptors(FileInterceptor('file', storage))
handleUploadFile(@Res() res, @UploadedFile() file: Express.Multer.File) {
  return res.status(HttpStatus.OK).json({
    success: true, 
    data: file.path   
  })
}

Angular 前端HTML模板(模板驱动表单)

<div class="upload-image">
    <input
      accept="image/*"
      type="file"
      class="form-control"
      placeholder="输入图片URL"
      ngModel
      name="image"
      (change)="onFileSelected($event)"
      [(ngModel)]="data.image"
      required
    />
</div>

Angular 前端方法

async addProduct(form: any) {
    if(this.image){
      const res = await this.uploadFileService()
      form.image = res.data
    }
}

image: any 
async onFileSelected(event: any){
   console.log(event);
   this.image = event.target.files[0]
   console.log('image: ', this.image);
}

uploadFileService(): Promise<any>{
    const formData = new FormData();
    formData.append('file', this.image);
    return firstValueFrom(
      this.http.post<any>(environment.baseApi + 'products/upload', formData)
    )
}

解决方案

1. 配置NestJS静态文件服务

在main.ts中添加静态文件服务,对外暴露存储图片的files目录:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { join } from 'path';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  // 配置静态文件访问路径,URL前缀设为'/files'
  app.useStaticAssets(join(__dirname, '..', 'files'), {
    prefix: '/files/',
  });
  await app.listen(3000);
}
bootstrap();

2. 修改后端返回的图片路径

将本地文件路径替换为可直接访问的HTTP URL,修改上传接口:

@Post('upload')
@UseInterceptors(FileInterceptor('file', storage))
handleUploadFile(@Req() req, @UploadedFile() file: Express.Multer.File) {
  // 拼接完整访问URL
  const imageUrl = `${req.protocol}://${req.get('host')}/files/${file.filename}`;
  return {
    success: true, 
    data: imageUrl   
  }
}

如果需要保留@Res()手动响应,可改为:

handleUploadFile(@Res() res, @Req() req, @UploadedFile() file: Express.Multer.File) {
  const imageUrl = `${req.protocol}://${req.get('host')}/files/${file.filename}`;
  return res.status(HttpStatus.OK).json({
    success: true, 
    data: imageUrl   
  })
}

3. 前端显示图片

数据库中存储的是完整的imageUrl,前端直接将其赋值给<img>的src属性即可:

<img [src]="product.image" alt="产品图片" />

内容的提问来源于stack exchange,提问作者Abduallah Barmu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:12:12