0

I have two API endpoints:

  1. /auth/

    method POST

    return Auth Token

  2. /report/stream/from/yyyy-mm-dd/to/yyyy-mm-dd/

    method GET

    return a .xlsx file

    this is the last code of endpoint

    res.set('Content-disposition', 'attachment; filename=' + report.getFilename() );
    res.set('Content-Type', 'application/vnd.openxmlformats- 
    officedocument.spreadsheetml.sheet');
    res.send(buffer);
    

Via Postman I can get the file without any errors/problems.

The Need:

To integrate these API in a PHP application.

The Scenario:

The PHP application has a form to ask the from/to dates and then perform an AJAX request to a PHP file.

The PHP AJAX script performs two requests (Auth and File) the code of PHP script:

$ch = @curl_init();
if($ch === false){
  @http_response_code(500);
  exit;
}
@curl_setopt($ch, CURLOPT_URL,            RPT_API_URL . "/auth/" );
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
@curl_setopt($ch, CURLOPT_POST,           1 );
@curl_setopt($ch, CURLOPT_POSTFIELDS,     'username='.RPT_USERNAME.'&password='.RPT_PASSWORD);
$result = @curl_exec($ch);
$errors = @curl_error($ch);
$http_code = @curl_getinfo($ch, CURLINFO_HTTP_CODE);
@curl_close($ch);

if ($http_code >= 300) {
  header('HTTP/1.1 503 Service Temporarily Unavailable');
  exit;
}

$out = json_decode($result);
$token = trim($out->token);

$ch = @curl_init();
if($ch === false){
  @http_response_code(500);
  exit;
}

@curl_setopt($ch, CURLOPT_URL,            RPT_API_URL . "/report/stream/from/2019-03-01/to/2019-03-31" );
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
@curl_setopt($ch, CURLOPT_HTTPHEADER,     array('Authorization: Bearer ' . $token));
@curl_setopt($ch, CURLOPT_HEADER,         true);
@curl_setopt($ch, CURLINFO_HEADER_OUT,    true);

$result = @curl_exec($ch);
$errors = @curl_error($ch);
$http_code = @curl_getinfo($ch, CURLINFO_HTTP_CODE);
$info = @curl_getinfo($ch);
$header_size = @curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($result, 0, $header_size);
$body = substr($result, $header_size);

@curl_close($ch);

if ($http_code >= 300) {
  header('HTTP/1.1 503 Service Temporarily Unavailable');
  exit;
}

preg_match('/filename=(.*?)\s/m', $headers, $matches);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=" . $matches[1] );
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header("Cache-Control: must-revalidate");
echo $body;
die();

The front end JS script is this one:

var dataToSend= { "from": "2019-01-14", "to": "2019-01-01" };
$.ajax({
    url: aj_url,
    type: "POST",
    data: dataToSend,
    headers: {
      Accept: 'application/octet-stream',
    }
}).done(function(res) {
    console.log(res);
    const a = document.createElement('a');
    a.style = 'display: none';
    document.body.appendChild(a);
    const blob = new Blob([res], {type: 'octet/stream'});
    const url = URL.createObjectURL(blob);
    a.href = url;
    a.download = 'test.xlsx';
    a.click();
    URL.revokeObjectURL(url);
});

ISSUE:

When I submit the form the AJAX PHP Script is performed correctly but the file that I get it seems wrong.

When I open it with Excel I get an error message with a dialog, I open the file but with a wrong number of worksheets.

Can you help me to fix the error and find a solution?

Zauker
  • 2,344
  • 3
  • 27
  • 36
  • 2
    Stop hiding errors by using the `@` and maybe PHP will help you find the issue – RiggsFolly May 13 '19 at 14:27
  • Don't know exactly but it sounds like the transfer gets interrupted ? If so, check https://stackoverflow.com/questions/9691057/php-apache-ajax-post-limit for example – St3an May 13 '19 at 14:28
  • @RiggsFolly I didn't receive PHP error. The file is streamed, but it seems is not well formatted. – Zauker May 13 '19 at 14:39
  • 1
    @St3an I'm trying the script in a local development environment where I have the API served by Node.js HTTP server and PHP application served by Gulp (Gulp PHP Connect). Maybe as you told I need to add a Content-Length information into che PHP header response? – Zauker May 13 '19 at 14:51
  • When I need to integrate PHP with node.js I use php-server-manager that is the same of Gulp PHP Connect. – dwpu May 13 '19 at 16:16
  • @Zauker unfortunately I don't know 'Gulp PHP Connect' at all... Can you try with a very little amount of data otherwise ?... – St3an May 14 '19 at 11:49

0 Answers0