web-dev-qa-db-fra.com

HTTPClient POST essaie d'analyser une réponse non-JSON

J'essaie de faire une demande dans Angular et je sais que la réponse HTTP ne sera pas en JSON mais Cependant, Angular semble attendre une réponse JSON puisque l'erreur est la suivante:

SyntaxError: Jeton inattendu <dans JSON à la position 0 dans JSON.parse () dans XMLHttpRequest.c

Aussi bien que

Echec de HTTP lors de l'analyse syntaxique pour http: // localhost: 9 ...

Ceci est la méthode 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)
    )
  );

et les en-têtes.

private httpOptions = {

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

) };

Je pensais que responseType: 'text' _ suffirait à faire Angular attendre une réponse non JSON.

16
Amy

Vous avez mis responseType: 'text' dans la mauvaise section de votre httpOptions - il devrait siéger à l’extérieur de headers, comme ceci:

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

Avec ce que vous aviez auparavant, un en-tête de requête de responseType était envoyé au serveur, plutôt que de simplement avoir une instruction à Angular pour traiter réellement la réponse en tant que texte.

16
Kirk Larkin

Ce code a finalement fonctionné pour moi afin de télécharger un fichier pdf (Angular 6/Laravel 5.6). La spécialité pour le téléchargement d’un fichier PDF par rapport à un fichier texte était '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.')
     }
  )
}

J'ai trouvé la solution par le biais de Kirk Larkins Answer (merci beaucoup!) Et d'un long angular sujet de github https://github.com/angular/angular/issues/18586 # issueecomment-323216764

8
Martin Eckleben

Si vous voulez juste recevoir un texte brut. Vous pouvez définir l'option Http sans en-tête.

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

Ci-dessous, l’appel du composant qui télécharge le blob, compatible avec IE et 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;
    });

Ci-dessous, la méthode de service qui spécifie le type de réponse à être "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);
}

Ci-dessous, le code qui appelle httpClient:

    //Make the service call:
    let obs = this.httpClient.request(method, url, options);
    //Return the observable:
    return obs;
0
Dilip Nannaware