前后端环境准备
首先确保已经搭建好基础的Angular前端项目和ExpressJS后端项目,后端需要安装必要的依赖包,前端需要引入HttpClient模块用于发送请求。后端项目需要先安装multer和相关依赖,执行以下命令:
npm install express multer cors
后端ExpressJS整合Multer配置
Multer基础配置
在后端项目中创建multer的配置文件,设置文件存储路径、文件名生成规则、上传限制等内容,具体配置代码如下:
const multer = require('multer');
const path = require('path');
// 配置存储路径和文件名
const storage = multer.diskStorage({
// 设置文件存储目录
destination: function (req, file, cb) {
cb(null, path.join(__dirname, 'uploads'));
},
// 生成唯一文件名,避免重复
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, uniqueSuffix + path.extname(file.originalname));
}
});
// 创建multer实例,设置上传限制
const upload = multer({
storage: storage,
limits: {
fileSize: 2 * 1024 * 1024, // 单个文件最大2MB
files: 5 // 最多上传5个文件
},
// 文件类型过滤,只允许图片类型
fileFilter: function (req, file, cb) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('只允许上传JPEG、PNG、GIF格式的图片'));
}
}
});
module.exports = upload;
编写上传接口
在后端主文件中引入配置好的multer,创建多图片上传接口,同时处理跨域问题,代码如下:
const express = require('express');
const cors = require('cors');
const upload = require('./multerConfig');
const app = express();
// 启用cors解决跨域问题
app.use(cors());
// 开放静态文件目录,用于访问上传后的图片
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
// 多图片上传接口,字段名为images,最多接收5个文件
app.post('/api/upload-images', upload.array('images', 5), (req, res) => {
try {
// 获取上传的文件信息
const files = req.files;
if (!files || files.length === 0) {
return res.status(400).json({ code: 400, message: '未检测到上传的文件' });
}
// 返回上传成功的文件信息
const fileList = files.map(file => ({
originalName: file.originalname,
fileName: file.filename,
filePath: `/uploads/${file.filename}`,
size: file.size
}));
res.json({ code: 200, message: '上传成功', data: fileList });
} catch (err) {
res.status(500).json({ code: 500, message: err.message });
}
});
// 启动服务
app.listen(3000, () => {
console.log('后端服务运行在3000端口');
});
前端Angular实现多图片上传
引入HttpClient模块
在Angular项目的app.module.ts中引入HttpClientModule,确保可以发送HTTP请求:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
bootstrap: [AppComponent]
})
export class AppModule {}
编写上传组件逻辑
在Angular组件中实现文件选择、文件上传的逻辑,代码如下:
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-upload',
templateUrl: './upload.component.html',
styleUrls: ['./upload.component.css']
})
export class UploadComponent {
selectedFiles: File[] = [];
uploadResult: any = null;
errorMessage: string = '';
constructor(private http: HttpClient) {}
// 选择文件事件
onFileSelected(event: any): void {
this.selectedFiles = Array.from(event.target.files);
this.errorMessage = '';
}
// 上传文件方法
uploadImages(): void {
if (this.selectedFiles.length === 0) {
this.errorMessage = '请先选择要上传的图片';
return;
}
// 创建FormData对象,append文件
const formData = new FormData();
this.selectedFiles.forEach(file => {
formData.append('images', file);
});
// 发送POST请求到后端接口
this.http.post('http://192.168.0.1:3000/api/upload-images', formData)
.subscribe({
next: (res) => {
this.uploadResult = res;
this.errorMessage = '';
},
error: (err) => {
this.errorMessage = err.error?.message || '上传失败,请重试';
this.uploadResult = null;
}
});
}
}
编写组件模板
组件的HTML模板代码如下,包含文件选择输入框、上传按钮和结果展示区域:
<div class="upload-container">
<h3>多图片上传</h3>
<div class="file-input">
<input type="file" multiple accept="image/*" (change)="onFileSelected($event)">
<p>已选择 {{ selectedFiles.length }} 个文件</p>
</div>
<button (click)="uploadImages()" [disabled]="selectedFiles.length === 0">开始上传</button>
<div class="error" *ngIf="errorMessage">{{ errorMessage }}</div>
<div class="result" *ngIf="uploadResult">
<h4>上传结果:</h4>
<p>状态码:{{ uploadResult.code }}</p>
<p>消息:{{ uploadResult.message }}</p>
<ul>
<li *ngFor="let item of uploadResult.data">
文件名:{{ item.originalName }},大小:{{ (item.size / 1024).toFixed(2) }}KB
</li>
</ul>
</div>
</div>
常见问题说明
- 确保后端uploads目录存在,否则会报文件存储路径错误
- 前端发送请求时,FormData中append的字段名需要和后端
upload.array()的第一个参数一致,否则无法接收到文件 - 如果前端运行端口和后端不同,需要确保后端已经正确配置cors,否则会出现跨域错误
- 上传大文件时可以适当调整multer的
fileSize限制,同时注意前端请求超时时间的设置