Angular 6:如何在进行 http 调用时将响应类型设置为文本

IT技术 javascript angular typescript
2021-02-07 19:31:16

我试图向 spring rest API 发出 http 请求。API 返回一个字符串值(“成功”或“失败”)...但我不知道如何在调用 API 时将响应类型设置为字符串值。 .其抛出错误为后端返回代码 200,主体为:[object Object]

我的角度代码如下所示,

订单.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ProductSearch } from '../_models/product-search';
import { ProductView } from '../_models/product-view';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ErrorHandlerService } from './error-handler.service';
import { Category } from '../_models/category';


@Injectable({
  providedIn: 'root'
})
export class OrderService {

  constructor(private http: HttpClient, private errorHandlerService: ErrorHandlerService) { }

addToCart(productId: number, quantity: number): Observable<any> {
    const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
    console.log("--------order.service.ts----------addToCart()-------productId:"+productId+":------quantity:"+quantity);
     return this.http.post<any>('http://localhost:8080/order/addtocart', 
              { dealerId: 13, createdBy: "-1", productId: productId, quantity: quantity}, 
              {headers: headers})
              .pipe(catchError(this.errorHandlerService.handleError));
    }
}

错误处理程序.service.ts

import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ErrorHandlerService {

  constructor() { }

  public handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  };

}

任何帮助将不胜感激...提前致谢...

6个回答

摆脱错误:

类型 '"text"' 不能分配给类型 '"json"'。

阅读Angular HTTP指南并使用

responseType: 'text' 作为 const

import { HttpClient, HttpHeaders } from '@angular/common/http';
.....
 return this.http
        .post<string>(
            this.baseUrl + '/Tickets/getTicket',
            JSON.stringify(value),
        { headers, responseType: 'text' as const }
        )
        .map(res => {
            return res;
        })
        .catch(this.handleError);
不确定“文本”作为“json”的作用,但它不是此处所述的干净解决方案:github.com/angular/angular/issues/18672#issuecomment-455435341
2021-03-19 19:31:16
@Random 没有必要“撒谎”typescript。如果你认为你必须这样做,那你就错了。接受的答案是正确的。
2021-03-22 19:31:16
我找不到这里“文本”作为“json”在做什么。您能否添加该结构的名称,或者甚至更好地解释该部分?
2021-03-23 19:31:16
@MichaelWestcott 这不是我评论的重点,但你是对的。'text' as 'json'正如之前的评论所要求的那样,我只是在解释这意味着什么
2021-03-25 19:31:16
实际上,responseType只允许 'json' 值。typescript知道这一点。所以写作'text' as 'json'意味着“我给你'文本'值,但对于类型检查,考虑我给你'json'”。所以typescript不会抱怨。这仅允许您对typescript“撒谎”。
2021-03-28 19:31:16

您不应该使用这些标头,标头决定了您发送的类型,并且您显然正在发送一个对象,即 JSON。

相反,您应该将选项设置responseTypetext

addToCart(productId: number, quantity: number): Observable<any> {
  const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');

  return this.http.post(
    'http://localhost:8080/order/addtocart', 
    { dealerId: 13, createdBy: "-1", productId, quantity }, 
    { headers, responseType: 'text'}
  ).pipe(catchError(this.errorHandlerService.handleError));
}
@rahulshalgar 我已经更新了我的答案。更改<any><string>
2021-03-24 19:31:16
抱歉..这是我的错误..但我现在收到另一个错误 error-handler.service.ts:21 后端返回代码 415,正文是:{"timestamp":"2018-06-11T13:45:32.875+0000 ","status":415,"error":"不支持的媒体类型","message":"不支持内容类型'application/json'","path":"/order/addtocart"}
2021-03-24 19:31:16
@rahulshalgar 显然您连接的后端不喜欢我发送的类型。您应该更改后端以接受 JSON 请求(这将使您的生活变得更加轻松,因为您正在发送对象)。或者把标题放回去。(我会更新我对后者的回答)
2021-04-12 19:31:16
它得到编译错误...[ts] '{ responseType: "text"; }' 不能分配给类型为 '{ headers?: HttpHeaders | 的参数 { [标题:字符串]:字符串 | string[]; }; 观察?:“身体”;参数?:Ht...'。属性“responseType”的类型不兼容。类型 '"text"' 不能分配给类型 '"json"'。
2021-04-13 19:31:16
@rahulshalgar 如果删除泛型类型注释会怎样?我看不出它不应该工作的理由
2021-04-14 19:31:16

在您的后端,您应该添加:

@RequestMapping(value="/blabla",  produces="text/plain" , method = RequestMethod.GET)

在前端(服务):

methodBlabla() 
{
  const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
  return this.http.get(this.url,{ headers, responseType: 'text'});
}

使用如下:

yourFunc(input: any):Observable<string> {
 var requestHeader = { headers: new HttpHeaders({ 'Content-Type': 'text/plain', 'No-Auth': 'False' })};
 const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
 return this.http.post<string>(this.yourBaseApi+ '/do-api', input, { headers, responseType: 'text' as 'json'  });
}
不工作,标题和响应类型部分有错误
2021-03-20 19:31:16
如果您使用非通用 post 方法,则可以删除 hacky 类型断言。
2021-04-12 19:31:16

对我来说,这种方式奏效了。requestOptions 作为对象

 returnObservable(): Observable<any> {
    const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
    const requestOptions: Object = {
      headers: headers,
      responseType: 'text'
    }
    return this.http.get<any>(this.streamURL , requestOptions);
 }