【问题标题】:Send multipart/form-data files with angular using $http使用 $http 发送带角度的 multipart/form-data 文件
【发布时间】:2016-06-13 19:44:42
【问题描述】:

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

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

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

headers: {
  'Content-Type': undefined
},

这会导致例如一张图片

Content-Type:image/png

虽然它应该是 multipart/form-data

另一个:

headers: {
  'Content-Type': multipart/form-data
},

但这需要一个边界标题,我认为不应该手动插入...

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

$httpProvider.defaults.headers.post['Content-Type'] = 'multipart/form-data; charset=utf-8';

但我不希望我的所有帖子都是多部分/表单数据。默认应该是 JSON

【问题讨论】:

    标签: angularjs http file-upload http-headers multipartform-data


    【解决方案1】:

    看一下 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(){
            });
        }
    

    【讨论】:

    • 刚刚确认,这个项目必须不再支持 IE 9,所以这对我来说是完美的!谢谢!
    • 这可行,但为什么Content-Type必须设置为undefined
    • @meucaa 代码 sn-p 看起来类似于此博客文章中的内容:“通过设置 'Content-Type': undefined,浏览器将 Content-Type 设置为 multipart/form-data为我们填写正确的边界。手动设置 'Content-Type': multipart/form-data 将无法填写请求的边界参数。” - uncorkedstudios.com/blog/…
    • 如果我有 base64(blob) 而不是文件,我该如何上传? @jstuartmilne
    • 我正在使用 ASP.NET Web API 后端,而这正是我们所需要的!但是,我不需要transformRequest 位。谢谢!
    【解决方案2】:

    这是 Angular 4 和 5 的更新答案。TransformRequest 和 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
        });
    }
    

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

    【讨论】:

    • 那么问题是 IE 11
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      在角度 9, 在尝试'Content-Type'之前:未定义,但它对我不起作用 然后 我尝试了下面的代码,它就像一个文件对象的魅力

      const request = this.http.post(url, data, {
            headers: {
              'Content-Type': 'file'
            },
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-13
        • 2013-04-09
        • 1970-01-01
        • 2019-04-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多