繁体   English   中英

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

[英]Send multipart/form-data files with angular using $http

我知道对此有很多问题,但我无法让它发挥作用:

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

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

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

这导致例如图像

Content-Type:image/png

虽然它应该是多部分/表单数据

和另一个:

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

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

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

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

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

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

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

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

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

在 angular 9中,在尝试 'Content-Type': undefined 之前,但它对我不起作用然后我尝试了下面的代码,它就像文件对象的魅力一样

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

Angular 13 (~13.0.0)中不需要指定请求的Content-Type

一些.service.ts:

public sendFiles(data: any): Observable<any> {
    const formData = new FormData();

    data.files.forEach((file: File) => {
      formData.append('files', file);
    });
    
    const url: string = <YOUR_API_URL>;

    return this.http.post<any>(url, formData);
}
  • Content-Type字段设置为以下值会导致错误:
    • '文件'
    • 未定义(不能激活严格模式)
    • '多部分/表单数据'

不要设置重置更新内置 FormData 的Content-Type 会解决的。 Angular 7中它可以工作。

虽然有一个Auth-Interceptor但我没有让它设置、更改或重置我的 post 请求的Content-Type标头。 让它保持现状,问题就解决了。

这是我通过请求传递的身份验证拦截器图像

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM