1

I'm writing a web-app with angular frontend and php backend in angular facing the challenge now, when trying to download a file it is loaded completely by the following script.

Angular service:

downloadFile(f:string){    
    this.http.post('/api/download.php', JSON.stringify({"file": f}), {responseType:'arraybuffer'})
    .subscribe(response => {
        console.log(response);
    });
}

Used imports:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

The PHP file looks like this (works fine):

  include "config/var.inc.php";
  $dir = "../" . DATA_FOLDER . "/";
  $data = json_decode(file_get_contents("php://input"));
  $file = $dir . $data->file;

  if(file_exists($file)){
    header('Content-Description: download audio');
    header('Content-Type: audio/mpeg');
    header('Content-Disposition: attachment; filename="' . basename($file) . '"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
  }

The console.log shows me the file is completely loaded (23300766 Bytes) enter image description here

How can I deliver it to the user as a download file?

LUXS
  • 343
  • 1
  • 2
  • 15

1 Answers1

0

You can use file-saver (https://www.npmjs.com/package/file-saver)

This is my piece of code:

import * as FileSaver from 'file-saver';

downloadTemplate(filePath: string) { // Example: filePath = '/file-path/download.docx'
    this.http.post(`http://endpoint/download`, filePath, { observe: 'response', responseType: 'blob' })
        .subscribe((response) => {
            this.saveFile(response);
        });
}

private saveFile(response) {
    const fileName = this.getFileNameFromHttpResponse(response);
    FileSaver.saveAs(response.body, fileName);
}

private getFileNameFromHttpResponse(httpResponse) {
    const contentDispositionHeader = httpResponse.headers.get('Content-Disposition');
    const result = contentDispositionHeader.split(';')[1].trim().split('=')[1];
    return result.replace(/"/g, '');
}

Note: If you want to get the file name from the response, you need to add this ("Access-Control-Expose-Headers: Content-Disposition") to the response header from the server.

Hieu Nguyen
  • 481
  • 4
  • 11