简体   繁体   中英

how to download a file with php and angular

I already uploaded a file and saved the path into my database, but the problem now is that I can't download it. I have already tested the PHP code and it works, but when I try to download it from the Angular side it doesn't. Instead I get this error in the console:

httpErrorResponse error: SyntaxError: Unexpected token p in JSON at position 0
  at JSON.parse (<anonymous>)
  at XMLHttpRequest.onLoad (localhost:4200/vendor.js:164415:51)
  at ZoneDelegate.invokeTask (localhost:4200/polyfills.js:9799:31)
  .........

ANGULAR SERVICE:

public getjointes(filepath:string){
  const params = new HttpParams()
    .set('filepath', filepath);
  return this.http.get(url+'/download.php', {params: params });
}

TYPESCRIPT / function

telecharger(path:string) {
    console.log(path);
    this.stream.getjointes(path).subscribe(response => {
        console.log(response);
    });
}

PHP CODE:

$rest = $_GET['filepath'] ;

echo($rest);
$filepath = 'upload/' . $rest;

if (file_exists($filepath)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($filepath));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize('upload/' . $rest));
    readfile('upload/' . $rest);
    header("Access-Control-Expose-Headers: Content-Disposition");   
}
else{
    echo ('noo');
}

Ok I'm going to assume the echo statements in your PHP are just for testing, based on the error messages you included in comments.

I think the problem you're having is that Angular assumes the response will be JSON and attempts to parse it. To avoid this behaviour , you can set the responseType parameter to "text" or "blob" (for binary data) in your code:

public getjointes(filepath:string) {
    const params = new HttpParams()
      .set('filepath', filepath);
    return this.http.get(url+'/download.php', {params: params, responseType: "text"});
}

Note that any output before a call to header() will result in the HTTP header not getting set. Your PHP code calls header() after readfile() . That header will be ignored. In addition, if a file is not found you should say so with a proper 404 header. This way your client-side code can respond properly to failures. Your PHP should look like this:

$rest = $_GET['filepath'];
$filepath = 'upload/' . $rest;

if (file_exists($filepath) && is_readable($filepath)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($filepath));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize('upload/' . $rest));
    header("Access-Control-Expose-Headers: Content-Disposition");   
    readfile('upload/' . $rest);
} else {
    header("HTTP/1.0 404 Not Found");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM