使用 Angular 和 Multer 上传多个文件
Uploading multiple files with Angular and Multer
我需要帮助来了解如何使用 Angular 7 处理 multer (nodeJS)。
我尝试了很多不同的情况,但似乎无法上传任何文件......
我的文件来自 ReactiveForm:
<mat-tab
label="Documents"
formGroupName="docs">
<mat-list>
<mat-nav-list>
<a mat-list-item
(click)="fsPicker.click()">
Upload financial statements
</a><input type="file" #fsPicker (change)="onDocPicked($event, 'fs')">
<a mat-list-item
(click)="cdPicker.click()">
Upload the constitutional documents
</a><input type="file" #cdPicker (change)="onDocPicked($event, 'cd')">
<a mat-list-item
(click)="idPicker.click()">
Upload the ID
</a><input type="file" #idPicker (change)="onDocPicked($event, 'id')">
<a mat-list-item
(click)="adPicker.click()">
Upload the bank account details
</a><input type="file" #adPicker (change)="onDocPicked($event, 'ad')">
</mat-nav-list>
</mat-list>
</mat-tab>
由 MimeValidator 控制:
// INSIDE NGONINIT:
this.customerForm = new FormGroup({
info: new FormGroup({
name: new FormControl(null, {validators: Validators.required}),
vat: new FormControl(null, {validators: Validators.required}),
}),
docs: new FormGroup({
fs: new FormControl(null, {asyncValidators: mimeType}),
cd: new FormControl(null, {asyncValidators: mimeType}),
id: new FormControl(null, {asyncValidators: mimeType}),
ad: new FormControl(null, {asyncValidators: mimeType})
})
});
// IN THE REST OF THE CLASS
onDocPicked(event: Event, type: string) {
const file = (event.target as HTMLInputElement).files[0];
this.customerForm.get('docs').patchValue({
[type]: file
});
this.customerForm.get('docs').get(type).updateValueAndValidity();
this.customerForm.get('docs').get(type).markAsDirty();
setTimeout(() => {
if (!this.customerForm.get('docs').get(type).valid) {
this.openAlert();
this.customerForm.get('docs').patchValue({
[type]: null
});
}
}, 100);
}
然后提交并发送到专属服务:
onSubmit() {
if (!this.customerForm.valid) {
return;
}
this.isLoading = true;
if (!this.editMode) {
this.customerService.addCustomer(this.customerForm.get('info').value, this.customerForm.get('docs').value);
this.customerForm.reset();
} else {
const updatedCustomer: Customer = {
id: this.id,
name: this.customerForm.get('info').value.name,
vat: this.customerForm.get('info').value.vat
};
this.customerService.updateCustomer(this.id, updatedCustomer);
}
this.router.navigate(['/customers']);
}
在服务内部,处理并发送到后端:
addCustomer(info, docsData) {
const customerData = new FormData();
customerData.append('name', info.name);
customerData.append('vat', info.vat);
customerData.append('docs', docsData);
console.log(docsData);
this.http.post<{message: string, customerId: string}>(
'http://localhost:3000/api/customers',
customerData
)
.subscribe((res) => {
const customer: Customer = {
id: res.customerId,
name: info.name,
vat: info.vat
};
this.customers.push(customer);
this.customersUpdated.next([...this.customers]);
});
}
最后但并非最不重要的由快递和 multer 接收和处理:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const isValid = MIME_TYPE_MAP[file.mimetype];
let err = new Error('invalid mime type!');
if (isValid) {
err = null;
}
cb(err, 'backend/docs');
},
filename: (req, file, cb) => {
const name = file.originalname.toLowerCase().split('').join('-');
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null, name + '-' + Date.now() + '.' + ext);
}
});
const upload = multer({storage: storage});
router.post('', upload.any(),
// .fields([
// {name: 'fs'},
// {name: 'cd'},
// {name: 'id'},
// {name: 'ad'},
// ]),
(req, res, next) => {
const customer = new Customer({
name: req.body.name,
vat: req.body.vat,
});
customer.save().then(result => {
res.status(201).json({
message: 'Customer added successfully!',
customerId: result.id
});
});
});
我认为问题出在我试图发送到服务器的对象...但我不确定如何正确处理这个问题。
即使通过调用 multer 的 any
命令,也不会保存任何内容。
这是 stackblitz 上完整项目的 link:
我发送的数据类型错误。为了更正(现在似乎可以工作),我必须在附加文件的 FormData 中精确:
const customerData = new FormData();
customerData.append('name', info.name);
customerData.append('vat', info.vat);
customerData.append('fs', docsData.fs as File, info.vat + 'fs');
customerData.append('cd', docsData.cd as File, info.vat + 'cd');
customerData.append('id', docsData.id as File, info.vat + 'id');
customerData.append('ad', docsData.ad as File, info.vat + 'ad');
完成后,我可以通过调用以下命令轻松地使用 multer 处理文件:
upload.
fields([
{name: 'fs', maxCount: 1},
{name: 'cd', maxCount: 1},
{name: 'id', maxCount: 1},
{name: 'ad', maxCount: 1},
]),
upload
变量是带有参数的 multer 实例(见问题)。
我需要帮助来了解如何使用 Angular 7 处理 multer (nodeJS)。 我尝试了很多不同的情况,但似乎无法上传任何文件...... 我的文件来自 ReactiveForm:
<mat-tab
label="Documents"
formGroupName="docs">
<mat-list>
<mat-nav-list>
<a mat-list-item
(click)="fsPicker.click()">
Upload financial statements
</a><input type="file" #fsPicker (change)="onDocPicked($event, 'fs')">
<a mat-list-item
(click)="cdPicker.click()">
Upload the constitutional documents
</a><input type="file" #cdPicker (change)="onDocPicked($event, 'cd')">
<a mat-list-item
(click)="idPicker.click()">
Upload the ID
</a><input type="file" #idPicker (change)="onDocPicked($event, 'id')">
<a mat-list-item
(click)="adPicker.click()">
Upload the bank account details
</a><input type="file" #adPicker (change)="onDocPicked($event, 'ad')">
</mat-nav-list>
</mat-list>
</mat-tab>
由 MimeValidator 控制:
// INSIDE NGONINIT:
this.customerForm = new FormGroup({
info: new FormGroup({
name: new FormControl(null, {validators: Validators.required}),
vat: new FormControl(null, {validators: Validators.required}),
}),
docs: new FormGroup({
fs: new FormControl(null, {asyncValidators: mimeType}),
cd: new FormControl(null, {asyncValidators: mimeType}),
id: new FormControl(null, {asyncValidators: mimeType}),
ad: new FormControl(null, {asyncValidators: mimeType})
})
});
// IN THE REST OF THE CLASS
onDocPicked(event: Event, type: string) {
const file = (event.target as HTMLInputElement).files[0];
this.customerForm.get('docs').patchValue({
[type]: file
});
this.customerForm.get('docs').get(type).updateValueAndValidity();
this.customerForm.get('docs').get(type).markAsDirty();
setTimeout(() => {
if (!this.customerForm.get('docs').get(type).valid) {
this.openAlert();
this.customerForm.get('docs').patchValue({
[type]: null
});
}
}, 100);
}
然后提交并发送到专属服务:
onSubmit() {
if (!this.customerForm.valid) {
return;
}
this.isLoading = true;
if (!this.editMode) {
this.customerService.addCustomer(this.customerForm.get('info').value, this.customerForm.get('docs').value);
this.customerForm.reset();
} else {
const updatedCustomer: Customer = {
id: this.id,
name: this.customerForm.get('info').value.name,
vat: this.customerForm.get('info').value.vat
};
this.customerService.updateCustomer(this.id, updatedCustomer);
}
this.router.navigate(['/customers']);
}
在服务内部,处理并发送到后端:
addCustomer(info, docsData) {
const customerData = new FormData();
customerData.append('name', info.name);
customerData.append('vat', info.vat);
customerData.append('docs', docsData);
console.log(docsData);
this.http.post<{message: string, customerId: string}>(
'http://localhost:3000/api/customers',
customerData
)
.subscribe((res) => {
const customer: Customer = {
id: res.customerId,
name: info.name,
vat: info.vat
};
this.customers.push(customer);
this.customersUpdated.next([...this.customers]);
});
}
最后但并非最不重要的由快递和 multer 接收和处理:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const isValid = MIME_TYPE_MAP[file.mimetype];
let err = new Error('invalid mime type!');
if (isValid) {
err = null;
}
cb(err, 'backend/docs');
},
filename: (req, file, cb) => {
const name = file.originalname.toLowerCase().split('').join('-');
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null, name + '-' + Date.now() + '.' + ext);
}
});
const upload = multer({storage: storage});
router.post('', upload.any(),
// .fields([
// {name: 'fs'},
// {name: 'cd'},
// {name: 'id'},
// {name: 'ad'},
// ]),
(req, res, next) => {
const customer = new Customer({
name: req.body.name,
vat: req.body.vat,
});
customer.save().then(result => {
res.status(201).json({
message: 'Customer added successfully!',
customerId: result.id
});
});
});
我认为问题出在我试图发送到服务器的对象...但我不确定如何正确处理这个问题。
即使通过调用 multer 的 any
命令,也不会保存任何内容。
这是 stackblitz 上完整项目的 link:
我发送的数据类型错误。为了更正(现在似乎可以工作),我必须在附加文件的 FormData 中精确:
const customerData = new FormData();
customerData.append('name', info.name);
customerData.append('vat', info.vat);
customerData.append('fs', docsData.fs as File, info.vat + 'fs');
customerData.append('cd', docsData.cd as File, info.vat + 'cd');
customerData.append('id', docsData.id as File, info.vat + 'id');
customerData.append('ad', docsData.ad as File, info.vat + 'ad');
完成后,我可以通过调用以下命令轻松地使用 multer 处理文件:
upload.
fields([
{name: 'fs', maxCount: 1},
{name: 'cd', maxCount: 1},
{name: 'id', maxCount: 1},
{name: 'ad', maxCount: 1},
]),
upload
变量是带有参数的 multer 实例(见问题)。