Получение октет-потока вместо изображения в узле js - PullRequest
0 голосов
/ 24 сентября 2018

В своем интерфейсе я использую 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>

Это машинописный текст

  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 показывает объект 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');  }
    })
  }

Служба захватываетформа контролирует и создает 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()));  
  }

В узле я использую грозный, чтобы получить файл и сохранить его.Это для тестирования.

  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 в обоих случаях. Я запутался, это проблема узла или угловая проблема?Как я могу это исправить ?

Спасибо

угловой 6, узел 8.11.1, грозный 1.2.1

1 Ответ

0 голосов
/ 30 сентября 2018

Проблема в том, что присвоение в событии удаления фактически не устанавливает значение ввода, поскольку входные данные файла не поддерживаются угловыми реактивными формами.Я говорю об этих строках:

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

Так что, когда вы пропускаете дело, вы вообще не отправляете файл на сервер.Вот почему данные, которые вы получаете, неверны.Здесь также есть ссылки на два других вопроса о переполнении стека о реактивных формах и загрузке файлов, где есть дополнительная информация по этой проблеме.

Существует два возможных решения этой проблемы.Во-первых, вы получаете ElementRef ввода файла с помощью запроса ViewChild.А затем напрямую назначьте файлы нативному элементу 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 , где вы можете увидеть весь код.

...