从服务器下载文件时的HttpErrorResponse

时间:2018-07-25 17:46:32

标签: angular http http-headers

我花了很多时间来使用'file-saver'角度模块来查找解决方案,以处理从我的apache服务器下载的文件。

在前端,用于下载的方法是:

 public download(document: any): void {
    const headers = new HttpHeaders();
    headers.append('Accept', 'application/octet-stream, */*');
    this.api.download(document.id, headers).subscribe((response) => {
      this._save(response);
    });
  }

“ api”执行以下操作:

  public download(id: number, headers: HttpHeaders): Observable<any> {
    return this.http.get<any>(
      Constants._ICE_API_ROOT + 'Download/' + id,
      { headers }
    );
 }

当我运行Angular App并检查控制台时,获取HttpErrorResponse:

HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://crmapi.wrk/Download/2", ok: false, …}

SyntaxError: Unexpected token P in JSON at position 0 at JSON.parse (<anonymous>) 

这似乎是正确的,因为服务器返回的内容就是我要下载的文件的内容...

在后端,PHP代码很简单:

$path = $document->folder . $document->name;
if (array_key_exists("HTTP_ACCESS_CONTROL_REQUEST_HEADERS", $_SERVER)) {
    header("Access-Control-Allow-Headers: " . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'] . "," . $document->type);
} else {
    header("Access-Control-Allow-Headers: " . $document->type);
}
header("Content-Disposition: attachment; filename=" . $document->name);
header("Content-Type: " . $document->type);
header("Content-Transfer-Encoding: Binary");
header("Content-Length:". $document->size);

readfile($path);
exit();

所以我的问题:

  • 从客户端发送的标头是否正确?
  • 服务器也发送了标头吗?
  • 为什么我的文件没有由Angular模块处理?

Thx

2 个答案:

答案 0 :(得分:1)

发送请求时,请在RequestOptions中使用{responseType: ResponseContentType.Blob}。从ResponseContentType导入@angular/http

希望通过this._save()您正在使用filesaver's saveAs()。虽然应该没问题,但是请尝试与this._save(response.blob())

一起使用


对于HttpClient,我认为没有ResponseContentType,我相信对您有用的是:{responseType: 'blob'}{responseType: 'text'}尝试。

您不必在请求中将其设置为标头,如以下注释中所指出的,responseTypeRequestOptions的一部分。请看一下:{{3} }

因此,基本上您的请求将类似于:

this.http.get<any>(url, { headers: yourHeaders, responseType: 'blob'});

答案 1 :(得分:0)

最后,根据@AshishRanjan解决方案,我以这种方式更新代码:

组件代码:

public download(document: any): void {
    const headers = new HttpHeaders();
    headers.append('Accept', document.type);
    this.api.download(document.id, headers).subscribe((response) => {
      this._save(response, document);
    });
  }


  private _save(rawDocument: Blob, document: any): void {
    saveAs(rawDocument, document.name);
  }

API:

public download(id: number, headers: HttpHeaders): Observable<any> {
    return this.http.get(
      Constants._ICE_API_ROOT + 'Download/' + id,
      { headers: headers, responseType: 'blob' as 'blob' }
    );
  }