gpt4 book ai didi

node.js - 在 Node js中获取八位字节流而不是图像

转载 作者:太空狗 更新时间:2023-10-29 17:15:09 25 4
gpt4 key购买 nike

在我的前端,我使用 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>

这是 typescript

  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];
}

因此,当放下图像时,从事件中获取它并将其放入文件输入中。提交表单后,将表单数据发送到服务进行发布。 console.log 显示一个文件对象 (__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'); }
})
}

该服务获取表单控件并构建一个 FormData 对象以发送到 Node 中。

  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()));
}

在 Node 中,我使用 formidable 来获取文件并保存它。这是为了测试。

  var form = new formidable.IncomingForm();

form.parse(req);
form.on('file', function (name, file){
console.log('file' , file);
});

问题是,如果我通过文件选择器选择了一个图像,我会得到一个类型为 image/jpeg 的文件、名称、路径和大小。

如果我通过拖放选择图像,我会得到一个application/octet-stream 类型的文件。它没有名称也没有大小。

我想在这两种情况下都得到image/jpeg我很困惑,这是 Node 问题还是 Angular 问题?我怎样才能解决这个问题 ?

谢谢

angular 6, node 8.11.1, formidable 1.2.1

最佳答案

问题是 drop 事件中的赋值实际上并没有设置输入的值,因为 Angular 响应式表单不支持文件输入。我说的是这一行:

let input = this.imageUpload.controls.imageInput as any;        
input.value = e.dataTransfer.files[0];

所以当你放下你的箱子时,你实际上根本没有将文件发送到服务器。这就是为什么你得到的数据是错误的。这里还有其他两个关于响应式(Reactive)表单和文件上传的堆栈溢出问题的链接,其中有关于此问题的更多信息。

有两种可能的解决方案可以解决此问题。第一个是使用 ViewChild 查询获取文件输入的 ElementRef。然后将文件直接分配给 native html 元素。这种方法的好处是您还会在文件输入中看到删除的文件名。缺点是这可能不适用于所有浏览器。关于 MDN 的官方文档说它适用于现代浏览器,但对我来说它确实适用于 Chrome 而不是 Edge。这是代码示例:

@ViewChild('imageInput') private imageInput: ElementRef;

public drop(e: DragEvent) {
e.preventDefault();
this.imageUpload.controls.imageInput.reset();
this.selectedFile = e.dataTransfer.files[0];
this.imageInput.nativeElement.files = e.dataTransfer.files;
}

另一种方法是您自己构建 FormData 对象,方法是在将所选文件发送到服务器之前在代码中自行添加所选文件。这应该可以在任何地方正常工作而不会出现问题。这是一个示例代码:

let formData = new FormData();
formData.append('imageInput', this.selectedFile);

我还创建了一个 StackBlitz您可以在其中查看所有代码的示例。

关于node.js - 在 Node js中获取八位字节流而不是图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52485412/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com