Reputation: 71
I am having problem receiving a Blob of Excel file using Angular 2+'s HttpClient get() method from a UserFrosting API.
Here is the code for the Userfrosting API:
public function apiGetAPExport(Request $request, Response $response, $args)
{
$objPHPExcel = $this->getAPExcelObject($apfilename); // create the PHPExcel Object.
// Redirect output to a client's web browser (Excel5)
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment;filename="'.$apfilename.'.xls"');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
header('Access-Control-Allow-Origin: *');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
exit;
}
I am using PHP Excel for generating the Excel file.
Here is the Angular functions:
btn_createAPfile(){
const url = this.AppService.fetchHost()+'/api/ap-export';
let req = this.http.get(url, {responseType: 'blob'})
.pipe(
map( // Log the result or error
data => {
console.log(data);
let blob = new Blob([data], { type: "application/vnd.ms-excel"});
return blob;
},
error => console.error("err: ", error)
)
);
req.subscribe(blob => {
console.log("dbg: ", blob);
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "apfile.xls";
link.click();
this.populateInvoices();
setTimeout(function () {
window.URL.revokeObjectURL(url);
}, 0);
});
}
What I'm trying to do here is to download the Excel file using http.get() and when the download is complete, re-populate a table of invoices with populateInvoices()
. But the problem is, I always get this error on my browser's console when I try to trigger the Angular function:
GET http://192.168.33.10/api/ap-export 500 (Internal Server Error)
Access to XMLHttpRequest at 'http://192.168.33.10/api/ap-export' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Uncaught HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}
I tried to directly input the URL to my browser's address bar and it is working fine.
I know I can do the download with windows.open()
but I can't repopulate the table with it.
Please help me, what am I missing here?
Upvotes: 1
Views: 136
Reputation: 1150
The error states that 192.168.33.10 has blocked cross origin resource sharing. Your web server isn't allowing a different server or URI to access the API.
Assuming you're using Apache then I've resolved similar issues as follows:
Create an .htaccess file in http://192.168.33.10/api/ containting
Header set Access-Control-Allow-Origin "*"
making sure you have headers mod enabled (linux example below):
sudo a2enmod headers
I also have in my notes that I needed to allow overrides in the directory the api resides in with in apache2.conf:
AllowOverride All
Reference and additional information: https://enable-cors.org/server_apache.html
Upvotes: 1