HTTPClient POST tries to parse a non-JSON response
我正在尝试在Angular中发出请求,并且我知道HTTP响应将不是JSON形式而是文本形式。 但是,Angular似乎期望JSON响应,因为错误如下:
SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse () at XMLHttpRequest.c
以及
Http failure during parsing for http://localhost:9...
这是post方法:
1 2 3 4 5 6 7 | 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) ) ); |
和标题。
1 2 3 4 5 6 7 8 9 | private httpOptions = { headers: new HttpHeaders({ 'Accept': 'text/html, application/xhtml+xml, */*', 'Content-Type': 'application/x-www-form-urlencoded', responseType: 'text' }, ) }; |
我认为
您已将
1 2 3 4 5 6 7 | private httpOptions = { headers: new HttpHeaders({ 'Accept': 'text/html, application/xhtml+xml, */*', 'Content-Type': 'application/x-www-form-urlencoded' }), responseType: 'text' }; |
像以前一样,
这段代码终于对我有用,可以xhr下载pdf文件(Angular 6 / Laravel 5.6)。
下载PDF文件与文本文件的专业是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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 Answer(非常感谢!)和长角github问题线程https://github.com/angular/angular/issues/18586#issuecomment-323216764找到了解决方案
如果您只想接收纯文本。您可以设置不带标题的Http选项。
1 2 | this.http.get("http://localhost:3000/login",{responseType: 'text'}) .subscribe((result)=>console.log(result)) |
下面给出的是来自下载blob的组件的调用,该组件与IE和chrome兼容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; }); |
下面给出的服务方法将响应类型指定为" blob"
1 2 3 4 5 | downloadReport(reportRequest: ReportRequest, password: string): Observable { let servicePath = `${basePath}/request/password/${password}`; this.httpOptions.responseType = 'blob'; return this.endpointService.post(endpoint, servicePath, reportRequest, this.httpOptions); } |
以下是进行httpClient调用的代码:
1 2 3 4 | //Make the service call: let obs = this.httpClient.request(method, url, options); //Return the observable: return obs; |
在有角度的更新之后,由于http客户端被更新为将响应解析为JSON,我遇到了同样的问题,当响应不包含有效的json(即文本或原始html)时失败。
为了避免自动进行json解析,请在get或post调用中将标头" responseType"添加为参数:
1 2 3 4 5 6 | this.http.get(template,{responseType:'text'}) .subscribe(result => { // result contains the"treated as text content" }); |
一般来说:
如果期望得到Json结果(例如在rest api中):
1 | HttpClient.get(url) // returns Observable Json formatted |
如果需要文本或原始html:
1 | HttpClient.get(url, {responseType:'text'}) // returns a string Observable |
如果返回类型是意外的(您还将获得标头,以便可以正确解析数据):
1 | HttpClient.get(url, {observe:response}) //returns Observable<HttpResponse < T >> |