HTTPClient POST пытается проанализировать ответ не-JSON
Я пытаюсь сделать запрос в Angular, и я знаю, что ответ HTTP будет не в JSON, а в текстовом формате. Тем не менее, похоже, что Angular ожидает ответа JSON, поскольку ошибка следующая:
SyntaxError: неожиданный токен <в JSON в позиции 0 в JSON.parse() в XMLHttpRequest.c
Так же как
Ошибка http во время синтаксического анализа для http://localhost: 9...
Это метод сообщения:
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.
Ответы
Ответ 1
Вы положили 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, чтобы фактически обрабатывать ответ как текст.
Ответ 2
Этот код, наконец, сработал для меня, чтобы загрузить 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.')
}
)
}
Я нашел решение с помощью ответа Кирка Ларкинса (большое спасибо!) и длинной angular проблемы с github. https://github.com/angular/angular/issues/18586#issuecomment-323216764
Ответ 3
Если вы просто хотите получить простой текст. Вы можете установить опцию Http без заголовка.
this.http.get("http://localhost:3000/login",{responseType: 'text'})
.subscribe((result)=>console.log(result))
Ответ 4
Ниже приведен вызов компонента, который загружает 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;