Angular: 无法设置 Http ResponseType

创建于 2017-08-08  ·  62评论  ·  资料来源: angular/angular

我提交一个...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

当前行为

无法为 HttpClient 方法设置响应类型。

        const options = {headers: headers, params: params, responseType: 'text'};

        return this.http.get(url, options).share();

会显示错误

  Types of property 'responseType' are incompatible.
    Type 'string' is not assignable to type '"json"'.

预期行为

预计响应类型应该像这样导出

export type ResponseType = 'arraybuffer' | 'blob' | 'json' | 'text';;

并且可以使用这种类型进行设置。 否则无法更改类型。

环境

Angular 版本:4.1.1,在 5.0.0-beta.2 中仍然存在
如此处所示: https ://github.com/angular/angular/blob/master/packages/common/http/src/client.ts

http feature

最有用的评论

@zaiddabaeen目前,这是设计使然。 Typescript 需要能够静态推断observeresponseType值,以便为get()选择正确的返回类型。 如果你传入一个类型不正确的options对象,它就不能推断出正确的返回类型。

另一种解决方法是:

const options = {headers, params, responseType: 'text' as 'text'};
return this.http.get(url, options).share();

所有62条评论

一种解决方法:

const options: {
            headers?: HttpHeaders,
            observe?: 'body',
            params?: HttpParams,
            reportProgress?: boolean,
            responseType: 'text',
            withCredentials?: boolean
        } = {
            headers: headers,
            params: params,
            responseType: 'text'
        };

@zaiddabaeen目前,这是设计使然。 Typescript 需要能够静态推断observeresponseType值,以便为get()选择正确的返回类型。 如果你传入一个类型不正确的options对象,它就不能推断出正确的返回类型。

另一种解决方法是:

const options = {headers, params, responseType: 'text' as 'text'};
return this.http.get(url, options).share();

我理解,但我认为这对开发人员来说是不直观且令人困惑的。 我不记得我以前曾将字符串转换为“字符串”。 按照建议枚举和使用类型对我来说听起来是一种更清洁的解决方案。

@zaiddabaeen问题出在:

const res = this.http.get(url, options);

res的类型是什么? 它取决于options中的值 - 但如果没有内联,Typescript 无法知道这些值是什么。

换句话说:

const res = this.http.get(url, {responseType: 'text'});

不等于

const options = {responseType: 'text'};
const res = this.http.get(url, options);

在第一个中,Typescript 可以推断出res的类型是Observable<string> ,在第二个中,它不能通过类型推断来确定。 如果我们添加此功能,我们将不得不返回一个Observable<any> ,这将是一个糟糕的体验。

我希望大多数情况下都可以使用扩展运算符来解决:

// Some options we want to control dynamically.
const options = {headers: ..., params: ...};
const res = this.http.get(url, {...options, responseType: 'text'});

这样,Typescript 可以根据签名和responseType的值推断返回类型,但也可以传入选项而不重构整个对象。

因此,我们必须采取变通办法来获得预期的效果? 这不可能是解决这个问题的方法。 我已经在我的电脑上尖叫了很长一段时间了,我有一个包装HttpClient但尝试设置responseType的服务不起作用,这是唯一的方法我可以通过执行responseType: 'text' as 'json'来消除错误。上述解决方法均无效。

@chrillewoodz然而,默认是 JSON。 你为什么要把它转换成json
我的方法有效,我可以确认它现在可以在生产环境中运行。

@zaiddabaeen我没有向 json 投射任何东西(据我所知)。 这就是我所拥有的:

  public get<T>(url: string, params?: {[key: string]: any}, headers?: HttpHeaders): Observable<T> {
    return this.http.get<T>(this.config.host + url, this.getRequestOptions(params, headers));
  }

  private getRequestOptions(params?: any, customHeaders?: HttpHeaders) {

    let defaultHeaders: HttpHeaders = new HttpHeaders();

    defaultHeaders = defaultHeaders.set('Content-Type', 'application/json');

    return {
      headers: customHeaders || defaultHeaders,
      params: params ? this.convertJSONtoParams(params) : null
    };
  }

尝试将responseType: 'text'添加到returngetRequestOptions是引发错误的原因。

使用responseType: 'text' as 'text'

上述解决方法均无效。

我已经尝试了以上所有方法:|

我也遇到了这个问题,但是通过从 get 调用中删除<T> ,我能够使用responseType: 'text'as 'text'让它工作。

例如,这不起作用并返回错误:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get<string>(url, options)

但这确实有效:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get(url, options)

我让它正常工作的唯一方法是使用@roddy的例子,那就是内联选项......

这不起作用:
image

也不会:
image

角v4.4.3

当 responseType 指定为json以外的值时,不得使用泛型,因为typeof T将被自动推断。

看看它是如何为get()方法定义的

    /**
     * Construct a GET request which interprets the body as an `ArrayBuffer` and returns it.
     *
     * <strong i="10">@return</strong> an `Observable` of the body as an `ArrayBuffer`.
     */
    get(url: string, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'arraybuffer';
        withCredentials?: boolean;
    }): Observable<ArrayBuffer>;
    /**
     * Construct a GET request which interprets the body as a `Blob` and returns it.
     *
     * <strong i="11">@return</strong> an `Observable` of the body as a `Blob`.
     */
    get(url: string, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'blob';
        withCredentials?: boolean;
    }): Observable<Blob>;
    /**
     * Construct a GET request which interprets the body as text and returns it.
     *
     * <strong i="12">@return</strong> an `Observable` of the body as a `string`.
     */
    get(url: string, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'text';
        withCredentials?: boolean;
    }): Observable<string>;
    /**
     * Construct a GET request which interprets the body as JSON and returns it.
     *
     * <strong i="13">@return</strong> an `Observable` of the body as an `Object`.
     */
    get(url: string, options?: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<Object>;
    /**
     * Construct a GET request which interprets the body as JSON and returns it.
     *
     * <strong i="14">@return</strong> an `Observable` of the body as type `T`.
     */
    get<T>(url: string, options?: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<T>;

这是非常有意义的,因为当 responseType 为json时,类型只能是 Angular 静态不知道的东西——所有其他情况都不需要泛型。

@reppners嗨 Stefan,感谢您的上述解释。 但是,无论我如何尝试,我都无法使新的 HttpClient 在我用来拦截应用程序中的图像 url 的服务中工作:

get(url: string): Observable<any> {
    return new Observable((observer: Subscriber<any>) => {
        let objectUrl: string = null;
          this.http
            .get(url, {headers: this.getHeaders(), responseType: ResponseContentType.Blob} )
            .subscribe(m => {
              objectUrl = URL.createObjectURL(m.blob());
              observer.next(objectUrl);
            });

        return () => {
          if (objectUrl) {
            URL.revokeObjectURL(objectUrl);
            objectUrl = null;
          }
        }
    });
  }
  getHeaders(): Headers {
    let headers = new Headers();

    let token = this.authService.getToken();
    if (token) {
      headers.set('Authorization', 'Bearer ' + token);
    }

    return headers;
  }

responseType: 'blob'既不是直接在 GET 请求中设置的,也不是在上面提到的options: { }中设置的。

@a-kolybelnikov 你可以在你的情况下使用这样的东西:

.get(url, { headers: this.getHeaders(), responseType: ResponseContentType.Blob as 'blob' })

@btory谢谢。 我已经尝试过了,它不会工作。

试试这个:..,responseType: 'text' as 'json'

谢谢@rds-rafael, this.http.get<ArrayBuffer>(this.pdfLink, {responseType: 'arraybuffer' as 'json'})为我工作,有点奇怪。

最后,解决方案是传递一个正确键入的参数。

对于 blob:
.get(url, { 'responseType: 'blob' as 'json' })

因此,无论谁赢得了以这种方式将 Http 重构为 HttpClient 的论点都是错误的。

@chrillewoodz的解决方案对我有用
我有类似的东西
this.httpClient.post<string>(url, data, {responseType: 'text' as 'json'});
这就像我被调用的api只是返回一个字符串。 当然,删除泛型意味着需要将整个内容更改为:
this.httpClient.post(url, data, {responseType: 'text' as 'text'});

虽然我发现解决这个问题的方法只是一个小烦恼,但实际上很难找到这个答案真的很麻烦。 如果有更好的文档记录,或者我认为可以找到更直观的解决方案,那就太好了。

@nortain你也绝对不需要。

this.httpClient.post(url, data, {responsesType: 'text'})

将为您提供Observable<string> ,而无需指定<string> 。 你不需要说'text' as 'text' ,Typescript 知道这一点。

您应该将类​​型参数传递给HttpClient方法的_only_时间是responseType: 'json' 。 所有其他都是隐含的。

@alxhub啊,谢谢,这更有意义,我意识到在删除通用名称时我没有尝试将其删除为“文本”。 还知道泛型用于 json 响应只会有帮助。 我很感激跟进。

@alxhub
observe属性面临同样的问题

this.http.get(endpoint, {
      observe: 'response'
    })
[ts]
Argument of type '{ headers: HttpHeaders; observe: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'observe' are incompatible.
    Type 'string' is not assignable to type '"body"'.

只有observe: 'body'有效。 'response''events'没有。

一切对我来说都非常令人费解。 我宁愿有不同的方法来调用不同的结果,而不是当前使用的推理。

@Pastafarian我同意,在一种情况下,我看到(使用相同的 responseType 选项):

返回 this.httpClient.request('发布','/登录',选项)

行得通,另一方面,这行不通:

return this.httpClient.post('/login', options)

不确定我是否同意这个 httpclient 比以前的版本更容易或更直观。 相反,它很笨重,并且依赖于很多幕后推论。

我真的跟不上。 刚刚在我的代码中偶然发现了这一点:

login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  const options = {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
    responseType: 'text'
  };
  return this.http.post(this.loginUrl, body, options);
}

使用最新版本的 VS Code,它在最后一行告诉我options是错误的:

Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'responseType' are incompatible.
    Type 'string' is not assignable to type '"json"'.

阅读评论,我觉得我必须写responseType: 'text' as 'text'responseType: 'text' as 'json'作为解决方法。 没看懂,这到底是什么意思?

@tobihagemann responseType: 'text' as 'text'是你想要的。 'text'不是'json'

谢谢,@alxhub。 我重新阅读了您的评论,我开始了解正在发生的事情(应该更仔细地阅读)。

我想我可以选择内联,不是内联而是强制转换,或者不是内联而是使用扩展运算符来处理与类型相关的事物,是吗? 基本上,这三个选项:

login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  return this.http.post(this.loginUrl, body, {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
    responseType: 'text'
  });
}
login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  const options = {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
    responseType: 'text' as 'text'
  };
  return this.http.post(this.loginUrl, body, options);
}
login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  const options = {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
  };
  return this.http.post(this.loginUrl, body, { ...options, responseType: 'text' });
}

as 'text'变体(第二个选项)真的是本期所述的“解决方法”吗? 或者它只是做事的方式? 有首选方案吗?

这是我的关键答案: https ://github.com/angular/angular/issues/18586#issuecomment -323216764

您必须在对get (或post )的调用中内联您的选项对象,以便 Typescript 编译器不会抱怨您的返回类型。

编译而不抱怨 res 不是 ArrayBuffer 的唯一方法是内联如下选项:

this.http.post<AuthResult>(this.AuthenticationEndpoint, 
    body, { withCredentials: false }).subscribe(res => {

整个方法是反直觉的化身。 我已经在这几天了,我仍然无法管理控制台记录带有参数和文件作为响应的发布请求的响应。

我正在拔头发。

好的,这对我有用:

动作.ts:

generatePOR(){
  this._api.generatePOR(this.selection).subscribe(res => {
    if(res !== null && res !== undefined){
      console.log(res.body);
    }
  }, (error) => console.log(error), () => {});
}

api.ts:

generatePOR(idList): any {
  const apiURL = `${this.API_URL}/purchaseorders/generatePOR`;
  this.PORresult = this._http.post(apiURL, idList, {
    observe: 'response',
    headers: new HttpHeaders({'Content-Type': 'application/json'}),
    responseType: 'text' as 'text'
  }).catch(this.handleError);
  return this.PORresult;
}

这是我针对此重大更改的解决方法。

const options: {
      headers?: HttpHeaders;
      observe: "response";
      params?: HttpParams;
      reportProgress?: boolean;
      responseType: "arraybuffer";
      withCredentials?: boolean;
    } = {
      observe: "response",
      responseType: "arraybuffer"
    };

this.http
    .get(blobRequest.url, options)
    .map(response => <ArrayBuffer>response.body)

似乎get甚至没有返回一个ArrayBuffer,而是一个Response对象。

我只是在下面添加并在角度 5 中运行良好。
常量 httpOptions = {
标头:新的 HttpHeaders({
'内容类型':'应用程序/json; 字符集=UTF-8'
}),
响应类型:“文本”作为“文本”
};
const body = JSON.stringify(params);
返回 this._http.post(url, body, httpOptions);

同样的问题发生在这里......添加'文本'作为'文本解决了它......

const httpOptions = {
            headers: new HttpHeaders({
              'Content-Type':  'application/json',
              'Accept': 'text/html'
            })
        };
return this.http.post<any>(url, { 'new': new_elements, 'old': old_elements }, {...httpOptions, responseType: 'text' as 'json' });

类似于这里的@jmoeyersons ... Angular 5.2.10

return this.http.post(
      url,
      data,
      { headers: headers, responseType: 'text' as 'text', withCredentials: false }).map(res => {
        console.log(res);
      });

或者

return this.http.post<any>(
      url,
      data,
      { headers: headers, responseType: 'text' as 'json', withCredentials: false }).map(res => {
        console.log(res);
      });

这根本没有很好的记录( https://angular.io/api/common/http/HttpClient#post )

TS很简单))

    const headers = new HttpHeaders({
        'Authorization': 'Bearer ' + token
    });
    const params = new HttpParams[]
    const observe = 'response';
    const reportProgress = false;
    const responseType = 'text';
    const withCredentials = false;

    const options = {
        headers: headers,
        observe: <any>observe,
        params: params,
        reportProgress: reportProgress,
        responseType: <any>responseType,
        withCredentials: withCredentials
    };

    return this.http.get<HttpResponse>(href, options);

看到像responseType: 'text' as 'text'这样的东西让我觉得很伤心。 也许整个 Http options对象应该是具有明确枚举类型的明确定义的接口。

@ghillert不幸的是,这会遇到同样的问题。 接口中字段的类型将是枚举类型,而不是特定值。 HttpClient的类型推断取决于传递给get()的对象的类型,该类型被缩小到特定的 _value_ 类型。

不过,这一切都有一个简单的解决方案:

const options = {
  headers: ...,
  params: ...,
  reportProgress: false,
  withCredentials: true,
};

return this.http.get(url, {...options, responseType: 'text'});

基本上,您只需在get()的调用中直接指定responseTypeobserve值。 其他所有内容都可以放入options对象中。

请在以下内容中提及:

https://angular.io/guide/http#requesting-non-json-data

我的代码:

return this.http.get<string>(this.apiURLDisplays+'/'+name, { responseType: 'text' })
            .pipe(
                catchError(this.handleError)
            );

我不明白 - ng serve 爆发了:

ERROR in src/app/shared/api.service.ts(937,68): error TS2345: Argument of type '{ responseType: "text"; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'responseType' are incompatible.
    Type '"text"' is not assignable to type '"json"'.

但它随后提供一个页面,它在浏览器中运行良好......所以这只是一个打字稿问题,它仍然以某种方式被转译成 javascript & 作品?

不过枚举会更好...

另外,我认为人们说'text' as 'json'有效的原因是在 VSCode 中,如果你有像上面我的get<string>() ,如果你有'text' as 'text'但接受,它会在它下面画一条红线'text' as 'json'

我刚刚阅读了@alxhub关于<string>在这种情况下隐含的评论,取出<string>并且 VSCode 接受return this.http.get(this.apiURLDisplays+'/'+name, { responseType: 'text' as 'text' })

通过同时使用 responseType 和身份验证服务,我能够使用它:

let headers2: HttpHeaders = new HttpHeaders({
      'Authorization' : 'my-auth-token'
});

this.httpClient.get(this.url, { headers : headers2, responseType : 'blob' }).subscribe(
  data => console.log(data),
  err => console.log(err)
)

在此之前,我试过这个:

const httpOptions2 = {
  headers: new HttpHeaders({
    'Authorization' : 'my-auth-token'
  }),
  responseType : 'blob'
};

this.httpClient.get(this.url, httpOptions2).subscribe(
  data => console.log(data),
  err => console.log(err)
)

...在 httpOptions2 作为参数它会给我

'{ headers: HttpHeaders; 类型的参数响应类型:字符串; }' 不能分配给类型为 '{ headers?: HttpHeaders | { [标题:字符串]:字符串 | 细绳[]; }; 观察?:“身体”; 参数?:Ht...'。

我不能使用后者的原因是什么?

*'my-auth-token' 已更改

@H36615

const httpOptions2 = {
  headers: new HttpHeaders({
    'Authorization' : 'my-auth-token'
  }),
  responseType : 'blob'
};

在此代码段中,TypeScript 将推断httpOptions2的类型为

{
  headers: HttpHeaders;
  responseType: string;
}

但是HttpClient要求如果您传递的options对象具有responseType和/或observe值,则它们具有特定类型,而不仅仅是string秒。

我在这里错过了什么吗? 我自己也遇到了这个错误,我期望 responseType blob。

const httpOptions = {
      ...
      responseType:'blob'
    };

我收到类型错误,但如果我这样做了

const httpOptions = {
      ...
      responseType:'blob' as 'blob'
    };

它工作得很好。 我认为这很荒谬是错的吗?

回答这是设计使然并不是一个好的答案,如果我可以创建 HttpRequest 并且该参数按预期工作,我希望它在任何地方都能正常工作。 使用该文档不会在任何地方提及这种 hacky 方法。

当然,我是 TypeScript 的新手,但它似乎不对我必须解决这样的解决方法,这是 TypeScript 问题还是 Angular?

我花了一天的大部分时间试图弄清楚为什么邮递员给出了正确的响应而 http.get 没有。 我想使用http:get可能有效,但没有。 最终我找到了这个线程,看到我不得不接受出去并使用 responseType: 'text' as 'text' 正如 roddy 去年 9 月建议的那样。 然后我读到了帖子的最后,发现还是有问题。 我认为这应该被修复,或者至少记录在案,因为它远非直观!

实际上,在最初的困惑之后再想一想,现在对我来说确实很有意义,就像
const httpOptions = { ... responseType:'blob' as 'blob' };
与在上面某处提到的@alxhub 在httpClient中插入文字符号不同。

我在blob类型的情况下所做的工作正常,在 Angular 6 中没有错误。
我尝试使用responseType: 'blob' as 'blob' ,但遇到语法错误并且无法构建它。

const options = {headers: this.httpHeaders, responseType: 'blob' as 'json'};
return this.http.get<Blob>(Constants.BASE_URL + Constants.DOWNLOAD_FILE + path, options
)

为我工作

_downloadWeb(url, api, mimeType) { var token = getTokenWeb(); let data = { "siteId": this.state.idSite } Axios.defaults.headers.common['Authorization'] = ${token} Axios.defaults.headers.common['Accept'] = ${mimeType} Axios.defaults.headers.common['Content-Type'] =应用程序/json Axios.post(url + api, data, { responseType: 'blob', }) .then((response) => { let blob = new Blob([response.data], { type: mimeType }); saveAs(blob, guid() + ".xlsx") }) .catch(function (error) { console.log("_downloadWeb", error); });; }

添加 responseType: 'blob' 将结果隐式更改为 Observable/ 可观察的>

不输入 httpClient.post 或 httpClient.get 为我解决了它

return this.httpClient.post<any>(
      `${environment.apiEndpoint}/${environment.apiVersion}/template-version/${templateId}/${version}/test`,
      { answers },
      { headers: this.blobHeaders, responseType: 'blob' })
      .pipe(
        tap(
          // Log the result or error
          data => console.log('You received data'),
          error => console.log(error)
        )
      );

给出错误,但是

return this.httpClient.post(
      `${environment.apiEndpoint}/${environment.apiVersion}/template-version/${templateId}/${version}/test`,
      { answers },
      { headers: this.blobHeaders, responseType: 'blob' })
      .pipe(
        tap(
          // Log the result or error
          data => console.log('You received data'),
          error => console.log(error)
        )
      );

作品

这个问题在 Angular 7.1 中仍然存在

我最终想出了这个,虽然我可以分享它:

// define this namespace somewhere
namespace ResponseType {
    export const JSON = 'json' as 'json';
    export const ArrayBuffer = 'arraybuffer' as 'arraybuffer';
    export const Blob = 'blob' as 'blob';
    export const Text = 'text' as 'text';
}

```打字稿
// 导入上面的命名空间并像这样使用它
常量 reqOpts = {
参数:参数,
标题:标题,
响应类型:响应类型.JSON,
};

// 没有类型错误,选择了正确的签名
const a = await this.http.get(url, reqOpts);
const b = 等待 this.http.get(网址,reqOpts);

https://github.com/angular/angular/issues/18586#issuecomment-327440092 gave a good hint at how to implement this.

This solution also work for the `observe` parameter.

____

Unless I missed something, this could be implemented in Angular directly, isn't ?

You would need to first put the following in the declaration `@angular/common/http/src/client.d.ts`:
```typescript
declare module '@angular/common/http' {
    export namespace HttpResponseType {
        export const JSON: 'json';
        export const ArrayBuffer: 'arraybuffer';
        export const Blob: 'blob';
        export const Text: 'text';
    }

    export declare type HttpObserve = 'body' | 'events' | 'response';
    export namespace HttpObserve {
        export const Body: 'body';
        export const Events: 'events';
        export const Response: 'response';
    }
}

然后在angular/packages/common/http/src/client.ts中实现它:

export namespace HttpResponseType {
    export const JSON: 'json' = 'json';
    export const ArrayBuffer: 'arraybuffer' = 'arraybuffer';
    export const Blob: 'blob' = 'blob';
    export const Text: 'text' = 'text';
}

export type HttpObserve = 'body' | 'events' | 'response';
export namespace HttpObserve {
    export const Body: 'body' = 'body';
    export const Events: 'events' = 'events';
    export const Response: 'response' = 'response';
}

最后,这两个命名空间应该被正确地导出到@angular/common/http

@rgoupil这是一个很酷的主意!

我有同样的问题。 在尝试实施上述一些建议半小时后,我没有继续执行以下操作(肮脏但......):

// I actually get the response type as a parameter to my function
const responseType = 'text';

const options = {
    headers: new HttpHeaders()
};

// @ts-ignore
options['responseType'] = responseType;

this.http.get(url, options);

我必须破解它
const options = {responseType: 'text' as 'json'};
this.httpClient.get<string>(url, options).subscribe()

将 httpOptions 变量转换为 Object 类型:

const httpOptions: Object = {
  responseType: 'blob'
};

文档中所述:https ://angular.io/api/common/http/HttpClient#get

有这方面的消息吗? 我一直在为 HttpClient.post 的选项上的相同问题而苦苦挣扎......

使用 Angular 7(8 尚未测试)

import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable()
export class RequestService {
  httpOptions = {
    headers: new HttpHeaders({
      Accept: 'application/json;charset=utf-8',
      Authorization: `Basic ${btoa('user:password')}`,
      'Content-Type': 'application/json;charset=utf-8'
    }),
    observe: 'response' as 'body'
  };

  constructor(private readonly httpClient: HttpClient) {
  }

  get<T>(uri: string): Observable<HttpResponse<T>> {
    return this.httpClient.get<HttpResponse<T>>(uri, this.httpOptions);
  }

  post<T>(uri: string, value: T): Observable<HttpResponse<T>> {
    return this.httpClient.post<HttpResponse<T>>(uri, value, this.httpOptions);
  }

  put<T>(uri: string, value: T): Observable<HttpResponse<T>> {
    return this.httpClient.put<HttpResponse<T>>(uri, value, this.httpOptions);
  }
}

我也遇到了这个问题,但是通过从 get 调用中删除<T> ,我能够使用responseType: 'text'as 'text'让它工作。

例如,这不起作用并返回错误:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get<string>(url, options)

但这确实有效:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get(url, options)

这个解决方案对我有用

它不起作用

const options= { 
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);

它确实有效

const options: any = {  //  The options with data type any does work well.
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);
const httpOptions: Object = {
  responseType: 'blob'
};

它不起作用

const options= { 
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);

它确实有效

const options: any = {  //  The options with data type any does work well.
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);

如果您只对设置responseType感兴趣并且可能涵盖遇到此问题的人的大多数情况,则将选项声明为anyObject很好。 但是,如果您想设置其他内容(例如标题),那么 typescript 将不再能够帮助您进行类型检查。 这就是我建议的原因,我更喜欢使用 _bracket notation_ 来设置 _responseType_ 的值,并且只使用 _ts-ignore_ 该行。

帮助我摆脱编译器错误( Type '"text"' is not assignable to type '"json"'. )的解决方案之一是使用构造函数创建HttpRequest 。 并使用http.request 。 我希望有人会帮助

此页面是否有帮助?
0 / 5 - 0 等级