在 post 请求中发送带有文件的数据
Sending data with a file in a post request
我正在使用 Angular 11 将文件发送到我的节点/express.js 后端如何将数据与文件一起发送?
我有一个名为 sources 的架构,另一个名为 files 的 files 架构包含 sources 架构 id,以指示哪些文件属于哪些源。
在我的 angular 应用程序中,我循环遍历从源文档中获取的数据以显示它们,显示的每个源都有一个上传文件的选项。
我希望能够在我的 post 请求中将源 ID 与文件一起发送,以便将其存储在我的数据库中。
这是我使用的代码:
source.component.ts
@Component({
selector: 'app-source',
templateUrl: './source.component.html',
styleUrls: ['./source.component.scss'],
})
export class SourceComponent implements OnInit {
showModal: boolean = false;
faUpload = faUpload;
@Input() datasource: {
_id: string;
name: string;
description: string;
imagePath: string;
};
@Input() searchPlaceHolder1: string;
@Input() searchPlaceHolder2: string;
isModalActive: boolean = false;
@Output() messageEvent = new EventEmitter<string>();
select: string = 'not selected yet';
searchText: string = '';
fileArr = [];
sheetArr = [];
fileObj = [];
form: FormGroup;
msg: string;
progress: number = 0;
isButtonVisible: boolean = true;
constructor(
public fb: FormBuilder,
private sanitizer: DomSanitizer,
public dragdropService: DragdropService
) {
this.form = this.fb.group({
txt: [null],
});
}
ngOnInit(): void {}
onSelect() {
this.select = 'selected';
}
sendMessage() {
this.messageEvent.emit(this.datasource.name);
}
upload(e) {
const fileListAsArray = Array.from(e);
fileListAsArray.forEach((item, i) => {
const file = e as HTMLInputElement;
const url = URL.createObjectURL(file[i]);
this.sheetArr.push(url);
this.fileArr.push({ item, url: url });
});
this.fileArr.forEach((item) => {
this.fileObj.push(item.item);
});
// Set files form control
this.form.patchValue({
txt: this.fileObj,
});
this.form.get('txt').updateValueAndValidity();
// Upload to server
this.dragdropService
.addFiles(this.form.value.txt)
.subscribe((event: HttpEvent<any>) => {
switch (event.type) {
case HttpEventType.Sent:
console.log('Request has been made!');
break;
case HttpEventType.ResponseHeader:
console.log('Response header has been received!');
break;
case HttpEventType.UploadProgress:
this.progress = Math.round((event.loaded / event.total) * 100);
console.log(`Uploaded! ${this.progress}%`);
break;
case HttpEventType.Response:
console.log('File uploaded successfully!', event.body);
setTimeout(() => {
this.progress = 0;
this.fileArr = [];
this.fileObj = [];
this.msg = 'File uploaded successfully!';
}, 3000);
}
});
}
// Clean Url
sanitize(url: string) {
return this.sanitizer.bypassSecurityTrustUrl(url);
}
loading = { 1: false, 2: false, 3: false, 4: false };
doSomething(i: number) {
console.log('Clicked');
this.loading[i] = true;
setTimeout(() => {
this.loading[i] = false;
}, 2000);
}
selectItem() {
this.showModal = true;
}
}
拖动-drop.service.ts
@Injectable({
providedIn: 'root',
})
export class DragdropService {
constructor(private http: HttpClient) {}
addFiles(sheets: File) {
var arr = [];
var formData = new FormData();
arr.push(sheets);
arr[0].forEach((item, i) => {
formData.append('txt', arr[0][i]);
});
return this.http
.post('http://localhost:4000/upload-file', formData, {
reportProgress: true,
observe: 'events',
})
.pipe(catchError(this.errorMgmt));
}
errorMgmt(error: HttpErrorResponse) {
let errorMessage = '';
if (error.error instanceof ErrorEvent) {
// Get client-side error
errorMessage = error.error.message;
} else {
// Get server-side error
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
console.log(errorMessage);
return throwError(errorMessage);
}
}
至于后端代码:
app.post("/upload-file", uploads.single("txt"), (req, res) => {
//convert csvfile to jsonArray
if (
req.file.mimetype === "application/vnd.ms-excel" ||
req.file.mimetype === "application/csv" ||
req.file.mimetype === "text / csv"
) {
const fileName = req.file.originalname;
csv({
delimiter: ";",
})
.fromFile(req.file.path)
.then((jsonObj) => {
//insertmany is used to save bulk data in database.
//saving the data in collection(table)
//finding the document using fileName and setting csvData as the jsonObj
sheetModel.findOneAndUpdate(
{ fileName: fileName },
{ $set: { csvData: jsonObj } },
{ upsert: true }, // if name does not exist insert
(err, csvData) => {
if (err) {
res.status(400).json({
message: "Something went wrong!",
});
} else {
res.status(200).json({
message: "File Uploaded Successfully!",
result: csvData,
});
}
}
);
});
}
只需将附加字段添加到 formData
,就像添加文件一样:
formData.append('sourceId', sourceId);
您似乎在服务器上使用了 Multer 中间件。根据文档,“req.body
将保留文本字段(如果有的话)”。
我正在使用 Angular 11 将文件发送到我的节点/express.js 后端如何将数据与文件一起发送?
我有一个名为 sources 的架构,另一个名为 files 的 files 架构包含 sources 架构 id,以指示哪些文件属于哪些源。 在我的 angular 应用程序中,我循环遍历从源文档中获取的数据以显示它们,显示的每个源都有一个上传文件的选项。
我希望能够在我的 post 请求中将源 ID 与文件一起发送,以便将其存储在我的数据库中。
这是我使用的代码:
source.component.ts
@Component({
selector: 'app-source',
templateUrl: './source.component.html',
styleUrls: ['./source.component.scss'],
})
export class SourceComponent implements OnInit {
showModal: boolean = false;
faUpload = faUpload;
@Input() datasource: {
_id: string;
name: string;
description: string;
imagePath: string;
};
@Input() searchPlaceHolder1: string;
@Input() searchPlaceHolder2: string;
isModalActive: boolean = false;
@Output() messageEvent = new EventEmitter<string>();
select: string = 'not selected yet';
searchText: string = '';
fileArr = [];
sheetArr = [];
fileObj = [];
form: FormGroup;
msg: string;
progress: number = 0;
isButtonVisible: boolean = true;
constructor(
public fb: FormBuilder,
private sanitizer: DomSanitizer,
public dragdropService: DragdropService
) {
this.form = this.fb.group({
txt: [null],
});
}
ngOnInit(): void {}
onSelect() {
this.select = 'selected';
}
sendMessage() {
this.messageEvent.emit(this.datasource.name);
}
upload(e) {
const fileListAsArray = Array.from(e);
fileListAsArray.forEach((item, i) => {
const file = e as HTMLInputElement;
const url = URL.createObjectURL(file[i]);
this.sheetArr.push(url);
this.fileArr.push({ item, url: url });
});
this.fileArr.forEach((item) => {
this.fileObj.push(item.item);
});
// Set files form control
this.form.patchValue({
txt: this.fileObj,
});
this.form.get('txt').updateValueAndValidity();
// Upload to server
this.dragdropService
.addFiles(this.form.value.txt)
.subscribe((event: HttpEvent<any>) => {
switch (event.type) {
case HttpEventType.Sent:
console.log('Request has been made!');
break;
case HttpEventType.ResponseHeader:
console.log('Response header has been received!');
break;
case HttpEventType.UploadProgress:
this.progress = Math.round((event.loaded / event.total) * 100);
console.log(`Uploaded! ${this.progress}%`);
break;
case HttpEventType.Response:
console.log('File uploaded successfully!', event.body);
setTimeout(() => {
this.progress = 0;
this.fileArr = [];
this.fileObj = [];
this.msg = 'File uploaded successfully!';
}, 3000);
}
});
}
// Clean Url
sanitize(url: string) {
return this.sanitizer.bypassSecurityTrustUrl(url);
}
loading = { 1: false, 2: false, 3: false, 4: false };
doSomething(i: number) {
console.log('Clicked');
this.loading[i] = true;
setTimeout(() => {
this.loading[i] = false;
}, 2000);
}
selectItem() {
this.showModal = true;
}
}
拖动-drop.service.ts
@Injectable({
providedIn: 'root',
})
export class DragdropService {
constructor(private http: HttpClient) {}
addFiles(sheets: File) {
var arr = [];
var formData = new FormData();
arr.push(sheets);
arr[0].forEach((item, i) => {
formData.append('txt', arr[0][i]);
});
return this.http
.post('http://localhost:4000/upload-file', formData, {
reportProgress: true,
observe: 'events',
})
.pipe(catchError(this.errorMgmt));
}
errorMgmt(error: HttpErrorResponse) {
let errorMessage = '';
if (error.error instanceof ErrorEvent) {
// Get client-side error
errorMessage = error.error.message;
} else {
// Get server-side error
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
console.log(errorMessage);
return throwError(errorMessage);
}
}
至于后端代码:
app.post("/upload-file", uploads.single("txt"), (req, res) => {
//convert csvfile to jsonArray
if (
req.file.mimetype === "application/vnd.ms-excel" ||
req.file.mimetype === "application/csv" ||
req.file.mimetype === "text / csv"
) {
const fileName = req.file.originalname;
csv({
delimiter: ";",
})
.fromFile(req.file.path)
.then((jsonObj) => {
//insertmany is used to save bulk data in database.
//saving the data in collection(table)
//finding the document using fileName and setting csvData as the jsonObj
sheetModel.findOneAndUpdate(
{ fileName: fileName },
{ $set: { csvData: jsonObj } },
{ upsert: true }, // if name does not exist insert
(err, csvData) => {
if (err) {
res.status(400).json({
message: "Something went wrong!",
});
} else {
res.status(200).json({
message: "File Uploaded Successfully!",
result: csvData,
});
}
}
);
});
}
只需将附加字段添加到 formData
,就像添加文件一样:
formData.append('sourceId', sourceId);
您似乎在服务器上使用了 Multer 中间件。根据文档,“req.body
将保留文本字段(如果有的话)”。