The error is occurring because the response object does not have a headers property. To get the filename from the response, you can modify the controller code to include the filename in the response body and then extract it in the JavaScript code. Here's an example:
Controller code:
public function export(){
$fileName = 'example.xlsx';
$headers = [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'Content-Disposition' => 'attachment; filename='.$fileName,
];
$data = [
'filename' => $fileName,
// add any other data you want to include in the response
];
return response()->json($data, 200, $headers);
}
JavaScript code:
$.ajax({
url: "{{ route('spatie.export') }}",
method: 'POST',
data: {
_token: "{{ csrf_token() }}",
dateStart: dateStart,
dateEnd: dateEnd,
action: action,
method: method
},
xhrFields: { responseType: "blob" },
success: function(response) {
var blob = new Blob([response]);
var reader = new FileReader();
reader.onload = function() {
var data = JSON.parse(reader.result);
var filename = data.filename;
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
};
reader.readAsText(response);
}
});
In this code, we're using response()->json() to send a JSON response with the filename included. In the JavaScript code, we're using FileReader to read the response as text and then parse the JSON data to get the filename. We can then use the filename to set the download attribute of the download link.