I am using Laravel's Storage facade and I am able to upload the pdf to S3 and I am also able to get() its contents but I cannot display or download it to the end user as an actual pdf file. It just looks like raw data. Here is the code:
$file = Storage::disk($storageLocation)->get($urlToPDF);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename='file.pdf'");
echo $file;
How can this be done? I have checked several articles (and SO) and none of them have worked for me.
I think something like this will do the job in L5.2:
public function download($path)
{
$fs = Storage::getDriver();
$stream = $fs->readStream($path);
return \Response::stream(function() use($stream) {
fpassthru($stream);
}, 200, [
"Content-Type" => $fs->getMimetype($path),
"Content-Length" => $fs->getSize($path),
"Content-disposition" => "attachment; filename=\"" .basename($path) . "\"",
]);
}
you can create a download url, using the getObjectUrl method
somthing like this:
$downloadUrl = $s3->getObjectUrl($bucketname, $file, '+5 minutes', array(
'ResponseContentDisposition' => 'attachment; filename=$file,'Content-Type' => 'application/octet-stream',
));
and pass that url to the user. that will direct the user to an amzon page which will start the file download (the link will be valid for 5 minutes - but you can change that)
another option, is first saving that file to your server, and then let the user download the file from your server
You can do with this code (replace with your directory and your file name) ....
Storage::disk('s3')->download('bucket-directory/filename');
If your bucket is private, this is the way to obtain a url to download the file.
$disk = \Storage::disk('s3');
if ($disk->exists($file)) {
$command = $disk->getDriver()->getAdapter()->getClient()->getCommand('GetObject', [
'Bucket' => \Config::get('filesystems.disks.s3.bucket'),
'Key' => $file,
'ResponseContentDisposition' => 'attachment;'
]);
$request = $disk->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');
$url = (string)$request->getUri();
return response()->json([
'status' => 'success',
'url' => $url
]);
}
In Laravel 5.7 it can be done with streamDownload:
return response()->streamDownload(function() use ($attachment) {
echo Storage::get($attachment->path);
}, $attachment->name);
$filename = 'test.pdf';
$filePath = storage_path($filename);
$header = [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$filename.'"'
];
return Response::make(file_get_contents($filePath), 200, $header);
$d = file_full_path_here...
$d = str_replace(' ', '%20', $d); //remove the white space in url
ob_end_clean();
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=" . $d);
header("Content-Type: application/pdf");
return readfile($d);
I figured it out. Silly mistake. I had to remove the single quotes from filename.
Fix:
$file = Storage::disk($storageLocation)->get($urlToPDF);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=file.pdf");
echo $file;
Related
This is the route for my controller and method:
Route::post('exportarDireccionTodos','MyController#exportarDireccionTodos');
I'm calling that route from a click button with javascript:
$.ajax({
url: baseUrl+'exportarDireccionTodos',
type: 'POST',
data: {'id': optionsChecked},
success: function(response) {
//etc
MyController have this code:
$delimiter=";";
$array = MyModel::findMany($todos)->toArray();
$filename = "direcciones.csv";
header("Content-Transfer-Encoding: UTF-8");
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="'.$filename.'";');
$f = fopen('php://output', 'wb');
foreach ($array as $line) {
fputcsv($f, $line, $delimiter);
}
fclose($f)
return response()->json([
'status' => 'success',
'mensaje' => 'Direcciones exportadas a CSV'
]);
I'm sending some id to my model then I'm creating a csv file, but I can't download it, I just see it pretty well made in the developer tools XHR, like this:
I've tried with:
header('Content-Type: application/force-download');
header('Content-Type: text/csv');
And with:
return Response::download($f, $filename, $headers); <-- here I got an error, Laravel 5.1 doesnt reconigze Response
same with:
return response()->download($f, $filename);
Always happens the same, the csv is made but can't download. I've tried 2 other ways to create the csv, but it always is well generated but can't be downloaded
You're missing the headers in your last call
return response()->download($f, $filename, $headers);
I'm using these headers on my laravel app to download a file
$headers = [
'Content-Type' => 'application/csv',
"Content-Description" => "File Transfer",
"Cache-Control" => "public",
'Content-Disposition' => 'attachment; filename="'.$filename.'"',
];
You may have better luck storing the file temporarily and generating a URL to download from
$fs = Storage::disk('local')->temporaryUrl($path, now()->addMinutes(5));
Well, the problem is my logic. I can't download a file with an ajax call.
I tried with Laravel-Excel but I had the same problem of coruse.
This thread fix my problem:
https://github.com/Maatwebsite/Laravel-Excel/issues/848
$response = array(
'name' => "das",
'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($archivo) //mime type of used format
);
and in the ajax:
var a = document.createElement("a");
a.href = response.file;
a.download = response.name;
document.body.appendChild(a);
a.click();
a.remove();
I have the following route that will load a file from the given URL, I need this to actually download the file (mp4, jpg, pdf) rather than open in the browsers in built viewer.
// Download from CDN Route
Route::get('cdn/{url}', function($url)
{
return Redirect::away($url);
})->where('url', '(.*)');
All files are stored externally so apparently Resource::download() wouldn't actually work.
All I have available to me is the Amazon URL: https://mybucket.s3.amazonaws.com/folder/filename.pdf
Any suggestions on how to force the browser to download the file from S3?
In my case simple anchor link is downloading the file ...
file name
Try this code.
Update composer with flysystem
$path = 'https://mybucket.s3.amazonaws.com/folder/filename.pdf';
if(Storage::disk('s3')->has($path)){
$data = Storage::disk('s3')->get($path);
$getMimeType = Storage::disk('s3')->getMimetype($path);
$newFileName = 'filename.pdf';
$headers = [
'Content-type' => $getMimeType,
'Content-Disposition'=>sprintf('attachment; filename="%s"', $newFileName)
];
return Response::make($data, 200, $headers);
}
pari answer download empty file.
$s3Client = AWS::createClient('s3');
$stream = $s3Client->getObject(
[
'Bucket' => 'bucket name',
'Key' => 'filename',
'SaveAs' => '/tmp'.filename
]);
return response($stream['Body'], 200)->withHeaders([
'Content-Type' => $stream['ContentType'],
'Content-Length' => $stream['ContentLength'],
'Content-Disposition' => 'attachment; filename="' .{filename with extention} . '"'
]);
How can we download a video with an external link from another server. It's not s3. It's a normal server, files are there, but it doesn't work. I have written this code
$filename = $video->video_id;
$tempFile = tempnam(sys_get_temp_dir(), $filename);
// dd($tempFile);
copy($video->path, $tempFile);
header("Content-Disposition: attachment; filename = ".$filename);
header("X-Accel-Redirect: ".$filename);
return response()->download($tempFile, $filename);
I have problem with my script, when i try to download ZIP files after creating - apache read them instead of downloading !!!
I use zipstream.php class (https://github.com/maennchen/ZipStream-PHP)
How to configure apache (running on Ubuntu) to let downloading this files with ZIP extension ?
Thank you !
Code i am using:
<?php
if($_GET['download'] == "ok")
{
$id = $_GET['id'];
$content = "TEST";
$mysql = $db_1->query("select result from testing where id='$id'");
$row = mysql_fetch_assoc($mysql);
$content .= $row['result'];
$file_opt = array(
'time' => time() - 2 * 3600,
'comment' => 'Simple Comment !',
);
$zip = new ZipStream('test.zip', array(
'comment' => 'Simple Comment !'
));
$zip->add_file('test.txt', $content, $file_opt);
$zip->finish();
exit;
}
Note: The problem is when i call the file from JQUERY he won't download, but when i browse it directly he download correctly !!
You're probably forgetting to set the zip header before echoing the content. Try this before you print the zip content:
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="myFileName.zip"');
Update: your lib seem to have a proper method to send the zip headers. Try to use this instead:
$zip = new ZipStream('test.zip', array(
'comment' => 'Simple Comment !',
'send_http_headers' => true,
));
This should work:
$filename = "test.zip";
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="' . $filename . '"');
readfile($filename);
I have a server set up to serve web pages on different domains (specifically a mobile device or localhost:9000 where laravel is serving on localhost:8000). I'm trying to return image requests on these pages to my laravel server but I'm running into problems. From a forum post, I thought that setting headers on a request would do the trick but, when I navigate to /api/v1/images/default.jpg, no default cat image is shown. Instead, I get a box with no image.
Now, the image is in my public folder so if I browse to /public/images/default.jpg I do see my cat image, but I'd rather serve images within my /api/v1/... route.
Route::get('images/{imageName}', function($imageName){
$img = 'public/images/' . $imageName;
// return $img;
echo $img . "\n\n";
if(File::exists($img)) {
// return "true";
// return Response::make($img, 200, array('content-type' => 'image/jpg'));
// return Response::download($img, $imageName);
// Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: inline; filename=\"".$imageName."\"");
header("Content-Type: image/jpg");
header("Content-Transfer-Encoding: binary");
//stream the file out
readfile($img);
exit;
} else {
return "false";
}
return $img;
// return File::exists($img);
// return File::isFile('/images/' . $imageName);
// return $imageName;
// if(File::isFile('images/' + $imageName)){
// return Response::make('images/' + $imageName, 200, array('content-type' => 'image/jpg'));
// }
});
Use the Response::stream method to do it:
Route::get('/image', function () {
return Response::stream(function () {
$filename = '/path/to/your/image.jpg';
readfile($filename);
}, 200, ['content-type' => 'image/jpeg']);
});
In case you want to stream your image from a ftp server ($imageName is the parameter)
$server = \Config::get('ftpconfig.server');
$usuario = \Config::get('ftpconfig.user');
$password = \Config::get('ftpconfig.password');
$path = \Config::get('ftpconfig.path');
$file_location = "ftp://$usuario:".urlencode($password)."#".$server.$path.$imageName;
$headers = [
"Content-Type" => "image/jpeg",
"Content-Length" => filesize($file_location),
"Content-disposition" => "inline; filename=\"" . basename($file_location) . "\"",
];
return \Response::stream(function () use ($file_location){
readfile($file_location);
}, 200, $headers)
#Andrew Allbright,
If your images are located inside the laravel app directory then you can use
$img = app_path().'/api/v1/images/' . $imageName;
For image manipulation you can try Intervention
This is the line of code which is giving me sick.
return Response::download(storage_path().'/file/' . $file->id . "." . $file->file->extension);
The files are uploaded and given an id which they are saved under e.g. 25.pdf this works fine if the file is a PDF but doesn't for anything else e.g. PNG. we upgraded from Laravel 3 to 4 to try to overcome this problem.
Any ideas?
EDIT:
I just uploaded a test text file with the word test in it once I uploaded it and then downloaded it I opened it, there were 3 blank lines and the letters te!!!!!I downloaded it through sftp and the file is correctly stored on the server so it is defiantly the download procedure!
I used this function instead of any of the Laravel stuff. :/
(Stolen from other places around the web)
public static function big_download($path, $name = null, array $headers = array()) {
if (is_null($name))
$name = basename($path);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$pathParts = pathinfo($path);
// Prepare the headers
$headers = array_merge(array(
'Content-Description' => 'File Transfer',
'Content-Type' => finfo_file($finfo, $path),
'Content-Transfer-Encoding' => 'binary',
'Expires' => 0,
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Pragma' => 'public',
'Content-Length' => File::size($path),
'Content-Disposition' => 'inline; filename="' . $name . '.' . $pathParts['extension'] . '"'
), $headers);
finfo_close($finfo);
$response = new Symfony\Component\HttpFoundation\Response('', 200, $headers);
// If there's a session we should save it now
if (Config::get('session.driver') !== '') {
Session::save();
}
// Below is from http://uk1.php.net/manual/en/function.fpassthru.php comments
session_write_close();
ob_end_clean();
$response->sendHeaders();
if ($file = fopen($path, 'rb')) {
while (!feof($file) and (connection_status() == 0)) {
print(fread($file, 1024 * 8));
flush();
}
fclose($file);
}
// Finish off, like Laravel would
Event::fire('laravel.done', array($response));
$response->foundation->finish();
exit;
}
One may ask, How can i get path to file in laravel?
Path to file can be achieved like:
public function getDownload(){
$file = public_path()."/downloads/info.pdf";
$headers = array('Content-Type: application/pdf',);
return Response::download($file, 'info.pdf',$headers);
}
function will download file from : 'project/public/download' folder.
(don't forget to set-up routes and controller by your self)
Try including the MIME in the return:
$file = storage_path().'/file/' . $file->id . "." . $file->file->extension;
return Response::download($file, 200, array('content-type' => 'image/png'));
If you are using Windows, go to php.ini and then uncomment "extension=php_fileinfo.dll" section and then use this code:
Route::get('file/download', function()
{
$file = public_path(). '\download\myfile.png';
return Response::download($file);
});