0

I am currently working on an AngularJS project with a server backend written in PHP. The frontend and backend communicate entirely in JSON, however, there is an export scenario where the server's output is not JSON encoded but instead a (text or binary) file.

The web application cannot just redirect the client's browser to a download URL as the server requires custom headers in the HTTP request (i.e. an API key) to serve the file. Therefore, I am using $http in AngularJS to initiate an AJAX request. Here is what happens:

File generation on the server side (using PHP with Slim framework):

$export = $this->model->export_cards($project_key);

$this->app->response()->status(200);
$this->app->response()->header("Content-Type", "text/plain");
$this->app->response()->header("Content-Disposition", "attachment; filename=\"export.txt\"");
$this->app->response()->header("Last-Modified", date("r");
$this->app->response()->header("Cache-Control", "cache, must-revalidate");
$this->app->response()->body($export);

$this->app->stop();

This is what happens on the client side (so far):

$http({
    method:     "get",
    url:        "/server/projects/cards/export_cards/" + $scope.key,
    headers:    {
        "X-API-Key":    session_service.get("api_key")
    }
}).then(
    function(response)
    {
        // Success, data received

        var data = response.data; // This variable contains the file contents (might be plain text, or even binary)

        // How do I get the browser to offer a file download dialog here?
    },
    function(response)
    {
        // Error handling
    }
);

I successfully receive the file contents in the AngularJS frontend and store them in a variable data. How do I get the browser to display a file download dialog?

The solution must work in Internet Explorer 10+ and reasonably recent versions of Firefox, Chrome and Safari (only desktop versions).

What is the best way to achieve this?

Thank you for your help and let me know if I need to provide any additional information.

Peter

pfolta
  • 73
  • 5

1 Answers1

0

I'm not sure this is possible.

Could you either:

Supply the API key directly, eg:

location.href = "/server/projects/cards/export_cards/" + $scope.key + '?api_key=' + session_service.get("api_key");

Or, have your API return a temporary, time-expiring URL for the file download, and then use location.href to access this URL.