我正在尝试在Angular中发出请求,我知道HTTP响应不是JSON而是文本。但是,Angular似乎期待JSON响应,因为错误如下:
SyntaxError:XMLHttpRequest.c中JSON.parse()位置0的JSON中的意外标记<
以及
解析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响应。
你把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发送指令以将响应实际视为文本。
这段代码终于让我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
下面给出的是从组件调用,下载blob,兼容IE和chrome:
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'
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);
}
以下是使httpClient调用的代码:
//Make the service call:
let obs = this.httpClient.request(method, url, options);
//Return the observable:
return obs;