HTTPClient POST尝试解析非JSON响应

时间:2018-06-12 22:10:47

标签: angular typescript angular-httpclient

我正在尝试在Angular中发出请求,我知道HTTP响应不是JSON ,而是文本。但是,Angular似乎期待JSON响应,因为错误如下:

  

SyntaxError:意外的令牌<在JSON位于JSON.parse的0位   ()XMLHttpRequest.c

以及

  

在解析http://localhost:9 ...

期间发生Http失败

这是post方法:

return this.http.post(this.loginUrl, this.createLoginFormData(username, password), this.httpOptions)
  .pipe(
    tap( // Log the result or error
      data => console.log(data);
      error => console.log(error)
    )
  );

和标题。

private httpOptions = {

  headers: new HttpHeaders({
    'Accept': 'text/html, application/xhtml+xml, */*',
    'Content-Type': 'application/x-www-form-urlencoded',
    responseType: 'text'
  },

) };

我认为responseType: 'text'足以使Angular期望非JSON响应。

6 个答案:

答案 0 :(得分:10)

您已将responseType: 'text'放入httpOptions的错误部分 - 它应位于headers之外,如下所示:

private httpOptions = {
  headers: new HttpHeaders({
    'Accept': 'text/html, application/xhtml+xml, */*',
    'Content-Type': 'application/x-www-form-urlencoded'
  }),
  responseType: 'text'
};

使用之前的内容,responseType的请求标头正在发送到服务器,而不是简单地向Angular发送指令以将响应实际视为文本。

答案 1 :(得分:4)

这段代码终于让我xhr下载了一个pdf文件(Angular 6 / Laravel 5.6)。 下载PDF文件与文本文件的专长是'responseType': 'blob' as 'json'

showPdf(filename: String){
  this.restService.downloadFile(
     'protected/getpdf',
     {'filename': filename}
  )
}

//method from restService
public downloadFile(endpoint:String, postData:Object){

  var restService = this

  var HTTPOptions = {
     headers: new HttpHeaders({
        'Accept':'application/pdf'
     }),
     'responseType': 'blob' as 'json'
  }

  this.http.post(this.baseurl+endpoint,postData,HTTPOptions )
  .subscribe(
     res => {
        console.log(res) //do something with the blob
     },
     error => {
        console.error('download error:', error)
     }, 
     () => {
        console.log('Completed file download.')
     }
  )
}

我通过Kirk Larkins找到了解决方案(非常感谢!)和一个长角度的github问题线程https://github.com/angular/angular/issues/18586#issuecomment-323216764

答案 2 :(得分:2)

默认情况下,Angular 将响应类型设置为 JSON。要覆盖它,您可以使用标头并将 responseType 设置为 'text' 或者一个简单的方法是这样的

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

答案 3 :(得分:1)

如果您只想接收纯文本。您可以设置不带标题的Http选项。

this.http.get("http://localhost:3000/login",{responseType: 'text'})
.subscribe((result)=>console.log(result))

答案 4 :(得分:0)

下面给出了来自组件的调用,该组件下载了与IE和chrome兼容的blob:

var mongoose = require('mongoose');
//define schema
var Schema= mongoose.Schema;
var ficheSchema= Schema({
  Datevisite: Date,
  Age:Number ,
  Pouls : Number ,
  TA : Number ,
  temperature : Number ,
  FR : Number,
  SAO2 : Number ,
  CGS : Number,
  antecedants : [String] ,
  motif :  String ,
  EVA:Number,
  id_patient : String
})



var fiche = mongoose.model('fiche',ficheSchema);
module.exports= fiche ;
//
app.get("/infopatient", (req, res) =>{
    var info = new fiches ( {
        Age:req.query.Age,
         Pouls : req.query.Pouls,
        TA:req.query.TA,
        temperature:req.query.temperature,
      FR:req.query.FR,
      SAO2:req.query.SAO2,
      CGS:req.query.CGS,
      EVA:req.query.EVA ,
      antecedants:[req.query.antecedants],
      Tmotif:req.query.motif}
      );
     info.antecedants.push([req.query.antecedants])
     info.save(function(err)
     {
        if(err) return handleError(err);
    });          
  })

下面给出的服务方法将响应类型指定为“ blob”

    this.subscribe(this.reportService.downloadReport(this.reportRequest, this.password), response => {
        let blob = new Blob([response], { type: 'application/zip' });
        let fileUrl = window.URL.createObjectURL(blob);
        if (window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(blob, fileUrl.split(':')[1] + '.zip');
        } else {
            this.reportDownloadName = fileUrl;
            window.open(fileUrl);
        }
        this.spinner = false;
        this.changeDetectorRef.markForCheck();
    },
    error => {
        this.spinner = false;
    });

下面是进行httpClient调用的代码:

downloadReport(reportRequest: ReportRequest, password: string): Observable<any> {
    let servicePath = `${basePath}/request/password/${password}`;
    this.httpOptions.responseType = 'blob';
    return this.endpointService.post(endpoint, servicePath, reportRequest, this.httpOptions);
}

答案 5 :(得分:0)

在有角度的更新之后,由于更新了http客户端以将响应解析为JSON,我也遇到了同样的问题,当响应不包含有效的json(即文本或原始html)时失败。

为避免自动json解析,请在get或post调用中将标头“ responseType”添加为参数:

this.http.get(template,{responseType:'text'})
  .subscribe(result => {

    // result contains the "treated as text content"

    });   

常规: 如果期望得到Json结果(例如在rest api中):

 HttpClient.get(url) // returns Observable Json formatted

如果需要文本或原始html:

HttpClient.get(url, {responseType:'text'}) // returns a string Observable 

如果返回类型是意外的(您还将获得标头,以便可以正确解析数据):

HttpClient.get(url, {observe:response}) //returns Observable<HttpResponse <T>>