簡體   English   中英

如何刪除 HTTP 攔截器中設置的內容類型以在 angular4 中上傳文件

[英]How to remove Content Type set in HTTP Interceptors for uploading a file in angular4

在我的應用程序中,我們在攔截器中設置了content-type = application/json 但是上傳文件內容類型應該是multipart/form-data ,即當我們嘗試上傳表單數據時,它將采用contant-type = multipart/form-data data 。 我的問題是如何在執行上傳文件的發布請求時刪除攔截器中設置的內容類型。

謝謝,哈沙瓦爾丹

刪除現有標題

 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')

我有一個類似的問題,最終通過在 body 上調用 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 的任何請求。

我正在使用 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,並根據request.body的實例更改content-type標頭:

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

檢查攔截器標頭中的傳入內容類型,如下所示:

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}`
         }

         });
          }
        }

我希望這對你有用!

您可以使用 Angular 的 HttpHeaders 提供的內置函數刪除

const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'my-required-content-type' }) }; httpOptions.headers.delete('Content-Type');

這樣,您可以使用名稱作為鍵來設置或刪除特定的標題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM