如何删除HTTP拦截器中设置的内容类型,以便在angular4中上传文件

时间:2018-05-30 18:04:30

标签: angular angular-http-interceptors

在我的应用程序中,我们在拦截器中设置了content-type = application/json。 但要上传文件内容类型应为multipart/form-data,即当我们尝试上传表单数据时需要contant-type = multipart/form-data。 我的问题是如何在执行上传文件的发布请求时删除拦截器中设置的内容类型。

感谢, Harshavardhan

5 个答案:

答案 0 :(得分:1)

删除现有标题

 if (!req.headers.has('Content-Type')) {
 req = req.clone({ headers: req.headers.delete('Content-Type','application/json') });

添加新标题

req = req.clone({ headers: req.headers.set('Content-Type', 'multipart/form-data')

检查标题的当前值。

req.headers.get('Accept')

答案 1 :(得分:1)

我遇到了类似的问题,并通过在主体上调用toString()来检查它是否为表单数据而最终解决了该问题。

我敢肯定有一种更干净的方法来检查对象的类型,但这对我来说已经足够好了:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let ignore =
        typeof req.body === "undefined"
        || req.body === null
        || req.body.toString() === "[object FormData]" // <-- This solves your problem
        || req.headers.has("Content-Type");

    if (ignore) {
        return next.handle(req);
    }

    const cloned = req.clone({
        headers: req.headers.set("Content-Type", 'application/json')
    });
    return next.handle(cloned);
}

请注意,我也忽略了任何手动指定了Content-Type的请求。

答案 2 :(得分:1)

检查拦截器标头中的传入内容类型,如下所示:

intercept(request:HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{

       // check whether we have form data
      if (request.body instanceof FormData) 
      {
            return request.clone({
           setHeaders:{
          'ContentType' : 'multipart/form-data',
           Authorization: `Bearer ${token}`

            }
          });
      }
       else{
             return request.clone({
          setHeaders:{
        'Content-Type': 'application/json',
         Authorization: `Bearer ${token}`
         }

         });
          }
        }

我希望对您有用!

答案 3 :(得分:0)

我正在使用一个Node.JS后端,该后端通常接受application/json内容类型。一个端点需要一个文件,该文件需要通过multipart/form-data格式发送。这可以通过使用FormData界面来实现。

因此,在将数据从Angular发送到后端之前,我使用了FormData接口:

onSubmit() {
  // ... some logic before

  // Need to post multipart/form-data to our server, so let's create a FormData instance:
  const formData = new FormData();
  formData.append('icon', this.selectedIcon, this.selectedIcon.name); // the actual file
  formData.append('name', this.createGroupForm.get('name').value); // other data from a Angular reactive form

  // Send the FormData to the service
  this.groupService.post(formData).subscribe((group) => {
    console.log({
      group,
    });
  });
}

现在,使用Angular HttpInterceptor实际上很容易检测您是发送普通数据还是FormData,并根据content-type的实例更改request.body标头:

export class ExampleInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    /**
     * Let's assume that we need to set the contentType to application/json for every request.
     */
    let contentType = 'application/json';

    /**
     * But when the data of the body is an instance of FormData, we can assume that we are uploading an file.
     * Therefore, we need to change the contentType to multipart/form-data.
     */
    if (request.body instanceof FormData) {
      // we are sending a file here
      contentType = 'multipart/form-data';
    }

    const clonedRequest= request.clone({
      setHeaders: {
        'content-type': contentType, // set the content-type here
      },
    });

    return next.handle(clonedRequest);
  }
}

答案 4 :(得分:0)

您可以使用Angular的HttpHeaders提供的内置功能删除

const httpOptions = { 标头:新的HttpHeaders({ 'Content-Type':'myrequired-content-type' }) }; httpOptions.headers.delete('Content-Type');

这样,您可以使用名称作为键来设置或删除特定的标题。