使用$ http发送带角度的multipart/form-data文件

Tho*_*bbe 37 file-upload http multipartform-data http-headers angularjs

我知道有很多关于此的问题,但我无法让这个工作:

我想在multipart/form-data中将文件从输入上传到服务器

我尝试了两种方法.第一:

headers: {
  'Content-Type': undefined
},
Run Code Online (Sandbox Code Playgroud)

这导致例如图像

Content-Type:image/png
Run Code Online (Sandbox Code Playgroud)

而它应该是multipart/form-data

和另外一个:

headers: {
  'Content-Type': multipart/form-data
},
Run Code Online (Sandbox Code Playgroud)

但这要求一个边界标题,我相信不应该手动插入...

什么是解决这个问题的干净方法?我读过你能做到的

$httpProvider.defaults.headers.post['Content-Type'] = 'multipart/form-data; charset=utf-8';
Run Code Online (Sandbox Code Playgroud)

但我不希望我的所有帖子都是multipart/form-data.默认值应为JSON

jst*_*lne 68

看一下FormData对象:https: //developer.mozilla.org/en/docs/Web/API/FormData

this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
        .success(function(){
        })
        .error(function(){
        });
    }
Run Code Online (Sandbox Code Playgroud)

  • 这有效,但为什么`Content-Type`必须设置为`undefined`? (7认同)
  • @meucaa该代码段类似于此博客文章中的内容,其中指出:“通过设置'Content-Type':未定义,浏览器会为我们将Content-Type设置为multipart / form-data并填写正确的边界。设置“内容类型”:multipart / form-data将无法填写请求的边界参数。” -https://www.uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs/ (3认同)

y3s*_*3sh 25

这是Angular 4&5的更新答案.FivertRequest和angular.identity被删除了.我还包括在一个请求中将文件与JSON数据组合的功能.

Angular 5解决方案:

import {HttpClient} from '@angular/common/http';

uploadFileToUrl(files, restObj, uploadUrl): Promise<any> {
  // Note that setting a content-type header
  // for mutlipart forms breaks some built in
  // request parsers like multer in express.
  const options = {} as any; // Set any options you like
  const formData = new FormData();

  // Append files to the virtual form.
  for (const file of files) {
    formData.append(file.name, file)
  }

  // Optional, append other kev:val rest data to the form.
  Object.keys(restObj).forEach(key => {
    formData.append(key, restObj[key]);
  });

  // Send it.
  return this.httpClient.post(uploadUrl, formData, options)
    .toPromise()
    .catch((e) => {
      // handle me
    });
}
Run Code Online (Sandbox Code Playgroud)

Angular 4解决方案:

// Note that these imports below are deprecated in Angular 5
import {Http, RequestOptions} from '@angular/http';

uploadFileToUrl(files, restObj, uploadUrl): Promise<any> {
  // Note that setting a content-type header
  // for mutlipart forms breaks some built in
  // request parsers like multer in express.
  const options = new RequestOptions();
  const formData = new FormData();

  // Append files to the virtual form.
  for (const file of files) {
    formData.append(file.name, file)
  }

  // Optional, append other kev:val rest data to the form.
  Object.keys(restObj).forEach(key => {
    formData.append(key, restObj[key]);
  });

  // Send it.
  return this.http.post(uploadUrl, formData, options)
    .toPromise()
    .catch((e) => {
      // handle me
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 然后问题是IE 11 (9认同)

小智 5

在 Angular 6 中,你可以这样做:

在您的服务文件中:

 function_name(data) {
    const url = `the_URL`;
    let input = new FormData();
    input.append('url', data);   // "url" as the key and "data" as value
    return this.http.post(url, input).pipe(map((resp: any) => resp));
  }
Run Code Online (Sandbox Code Playgroud)

在 component.ts 文件中:在任何函数中,例如 xyz,

xyz(){
this.Your_service_alias.function_name(data).subscribe(d => {   // "data" can be your file or image in base64 or other encoding
      console.log(d);
    });
}
Run Code Online (Sandbox Code Playgroud)