sle*_*vin 8 file-upload node.js formidable angular
在我的前端,我使用angular6,我有这种形式,您可以通过删除文件div或单击div打开文件选择器来选择图像.
表格是
<form [formGroup]="imageUpload" (ngSubmit)="imageUploadSubmitted($event.target)" >
<div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop></div>
<input type="file" (change)='imageChange($event)' #imageInput id="imageInput" name = 'imageInput' accept=".png, .jpg, .jpeg, .gif" formControlName="imageInput" required >
<button type="submit" >Submit</button>
</form>
Run Code Online (Sandbox Code Playgroud)
这是打字稿
selectedFile:File=null;
allowDrop(e) {
e.preventDefault();
}
drop(e) {
e.preventDefault();
this.imageUpload.controls.imageInput.reset();
this.selectedFile = e.dataTransfer.files[0];
let input = this.imageUpload.controls.imageInput as any;
input.value = e.dataTransfer.files[0];
}
imageChange(e){
this.selectedFile = e.target.files[0];
}
Run Code Online (Sandbox Code Playgroud)
因此,在删除图像时,从事件中获取它并将其放入文件输入中.提交表单后,将表单数据发送到服务进行发布.该console.log显示File对象(__proto__ : File无论你从文件选择器中选择了一个图像,或者一个下降的)div.
imageUploadSubmitted(form){
console.log('imageInput value - ', this.imageUpload.controls.imageInput.value);
this.mapcmsService.uploadImage(form).subscribe((data) =>{
if(data.success){ alert('all good'); }
else{ alert('error'); }
})
}
Run Code Online (Sandbox Code Playgroud)
该服务获取表单控件并构建一个FormData要在节点中发送的对象.
uploadImage(data){
let formData = new FormData(data);
let headers = new Headers();
headers.append('Authorization',this.userToken);
return this.http.post('http://localhost:3000/user/upload/image', formData ,{headers:headers} ).pipe(map(res => res.json()));
}
Run Code Online (Sandbox Code Playgroud)
在节点中,我使用formidable来获取文件并保存.这是为了测试.
var form = new formidable.IncomingForm();
form.parse(req);
form.on('file', function (name, file){
console.log('file' , file);
});
Run Code Online (Sandbox Code Playgroud)
问题是,如果我通过文件选择器选择了一个图像,我会得到一个类型的文件image/jpeg,一个名称,一个路径和一个大小.
如果我通过拖放选择图像,我会得到一个类型的文件application/octet-stream.这没有名字,没有大小.
我想image/jpeg在两种情况下都能得到.我很困惑,这是节点还是角度问题?我怎样才能解决这个问题 ?
谢谢
角度6,节点8.11.1,强大的1.2.1
问题是 drop 事件中的赋值实际上并没有设置输入的值,因为 Angular 反应式表单不支持文件输入。我正在谈论这一行:
\n\nlet input = this.imageUpload.controls.imageInput as any; \ninput.value = e.dataTransfer.files[0];\nRun Code Online (Sandbox Code Playgroud)\n\n因此,当您提交案例时,您实际上根本没有将文件发送到服务器。这就是为什么你得到的数据是错误的。这里还有关于反应式表单和文件上传的其他两个堆栈溢出问题的链接,其中有有关此问题的更多信息。
\n\n\n\n有两种可能的解决方案可以解决此问题。第一个是ElementRef通过使用查询获取文件输入ViewChild。然后直接将文件分配给原生html元素。这种方法的好处是您还将在文件输入中看到删除的文件名。缺点是这可能不适用于所有浏览器。MDN上的官方文档说它可以在现代浏览器中运行,但对我来说它可以在 Chrome 中运行,但不能在 Edge 中运行。\n下面是代码示例:
@ViewChild(\'imageInput\') private imageInput: ElementRef;\n\npublic drop(e: DragEvent) { \n e.preventDefault();\n this.imageUpload.controls.imageInput.reset(); \n this.selectedFile = e.dataTransfer.files[0];\n this.imageInput.nativeElement.files = e.dataTransfer.files;\n }\nRun Code Online (Sandbox Code Playgroud)\n\n另一种方法是您自己构建 FormData 对象,方法是在代码中自行添加所选文件,然后将其发送到服务器。这应该可以在任何地方工作而没有问题。这是示例代码:
\n\nlet formData = new FormData();\nformData.append(\'imageInput\', this.selectedFile);\nRun Code Online (Sandbox Code Playgroud)\n\n我还创建了一个StackBlitz示例,您可以在其中查看所有代码。
\n| 归档时间: |
|
| 查看次数: |
616 次 |
| 最近记录: |