【问题标题】:Angular 5 'Content-Type': 'multipart/form-data' gets reset to 'application/json'Angular 5 'Content-Type':'multipart/form-data' 被重置为 'application/json'
【发布时间】:2018-12-16 02:58:05
【问题描述】:

您好,我无法让我的 httpClient 补丁请求发送内容类型为“multipart/form-data”的 FormData。

我已经指定了如下所示的标题:

  private httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'multipart/form-data', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache'
    })
  };

我执行以下操作以保存到 nodejs 服务器:

const formData: FormData = new FormData();
formData.append('materialFile', 'something');
return this.httpClient.patch<any>(this.apiUrl  + loan.id, formData, this.httpOptions);

在我的 Nodejs/Express 服务器上,我执行以下操作:

const Multer  = require('multer');

router.patch('/:id', Multer().fields([{ name: "materialFile", maxCount: 1 }]), (req, res, next) => {
  console.log(req.files['materialFile']);
});

当我在浏览器上检查请求标头时,我发现内容类型是 application/json。

有人知道为什么吗?

【问题讨论】:

  • 为什么要在 PATCH 请求中发送表单数据?表单数据应该在 POST 中发送,我认为 Angular 正在识别这一点,而是改变了你的内容类型
  • @Dummy 我把它改成 post 还是一样
  • 如果您想收到完整的回复,请使用observe:response,请参阅angular.io/guide/http#reading-the-full-response
  • 能否在浏览器的开发者工具中显示 xhr 请求状态? (Ctrl+shift+i) -> network -> xhr 从您的应用发送请求并显示 xhr 响应 @ShaunChua
  • @Debojyoti 拦截器是问题所在,谢谢

标签: angular express angular5 multer angular-httpclient


【解决方案1】:

Angular 会尝试根据请求体自动设置http header content-type,所以完全不需要手动设置。如果 content-type 标头在浏览器的 devtools 中为 application/json,则意味着请求正文已更改,直到 angular 尝试定义标头。这种变化很可能发生在拦截器中。因此,如果您有一个拦截器,可以对请求进行操作,那么问题可能就在那个时候。

【讨论】:

  • 你绝对救了我的命!上帝保佑!
  • 我必须同意!我花了将近一个星期和很多很多时间才发现我的 Angular 应用程序有一个 jwt 拦截器,它强制标头为 application/json。愚蠢的部分是我从未抓住它,因为我仍在发送标题和我的帖子,所以我认为我没有设置任何默认值,但我确实做到了。这是我最喜欢的新帖子!
【解决方案2】:

正如 Hikmat G. 指出的那样,问题很可能源于 Http 拦截器,就我而言,我发现在我用来注入 JWT 令牌的授权拦截器中,将内容类型设置为 @987654322 @如下图:

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

我确实需要它,除了某个请求,我将文件作为 formdata 对象的一部分发送,其中内容类型必须是multipart/form-data,它将自动更改为 json,所以我添加了一个条件以避免该问题,它似乎正在工作:

        let json_blacklist = "/example/url";
        let reqHeaders = {
            setHeaders: {
            'Content-Type' :  'application/json',
            'Accept': 'application/json',
            'Authorization': `Bearer ${ token }`,
            },
        };

        if(req.url.includes(json_blacklist)) {
            delete reqHeaders.setHeaders["Content-Type"];
        }

        return req.clone(reqHeaders);

提示:对于发送文件的请求,不要将内容类型设置为 multipart/form-data,只需完全删除内容类型并允许浏览器设置内容类型本身,这将有助于防止 webkit 边界错误,因为浏览器会自动设置边界,有关更多详细信息,请参阅#40561738

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 1970-01-01
    • 2015-12-20
    • 2021-08-28
    • 2022-07-23
    • 1970-01-01
    • 2019-10-26
    • 2016-10-02
    • 2020-11-26
    相关资源
    最近更新 更多