欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

laravel force download image 强制下载 jpg png gif 图像 image 有大用

Laravel : Force the download of a string without having to create a file

I'm generating a CSV, and I want Laravel to force its download, but the documentation only mentions I can download files that already exist on the server, and I want to do it without saving the data as a file.

I managed to make this (which works), but I wanted to know if there was another, neater way.

    $headers = [
        'Content-type'        => 'text/csv',
        'Content-Disposition' => 'attachment; filename="download.csv"',
    ];
    return \Response::make($content, 200, $headers);

I also tried with a SplTempFileObject(), but I got the following error : The file "php://temp" does not exist

    $tmpFile = new \SplTempFileObject();
    $tmpFile->fwrite($content);

    return response()->download($tmpFile);
shareimprove this questionedited Jan 2 '17 at 21:50asked Jan 2 '17 at 11:17Marc Brillault6661623

1 the content disposition approach is the cleanest way – Brian Dillingham Jan 2 '17 at 21:54   Thanks ! I'd really like to know if there is a reason why there isn't any built-in function for that. – Marc Brillault Jan 2 '17 at 22:25

2 Answers 正确答案

Make a response macro for a cleaner content-disposition / laravel approach

Add the following to your App\Providers\AppServiceProvider boot method

\Response::macro('attachment', function ($content) {

    $headers = [
        'Content-type'        => 'text/csv',
        'Content-Disposition' => 'attachment; filename="download.csv"',
    ];

    return \Response::make($content, 200, $headers);

});

then in your controller or routes you can return the following

return response()->attachment($content);
shareimprove this answeredited Jan 2 '17 at 22:53answered Jan 2 '17 at 22:39Brian Dillingham4,99911136

add a comment



好像 return $response = Response::make($content)->header('Content-Type', 'image/png'); 是同样的原理


Try this:

// Directory file csv, You can use "public_path()" if the file is in the public folder
$file= public_path(). "/download.csv";
$headers = ['Content-Type: text/csv'];

 //L4
return ($file, 'filename.csv', $headers);
//L5 or Higher
return ($file, 'filename.csv', $headers);
shareimprove this answeranswered Jan 2 '17 at 14:48Paulo Costa224

   Sorry, but I wanted a way which wouldn't force me to save the file beforehand. – Marc Brillault Jan 2 '17 at 14:49

来自  https://stackoverflow.com/questions/41425812/laravel-force-the-download-of-a-string-without-having-t...




Laravel 5.5 - Force Download File using response helper


We may sometime require to download zip or pdf file for report or invoice in Laravel 5 application. So in this article i will let you know how to force download file using response "download()" method.


As we know, we have to make response from controller for download file. So you have to simple return response with download().


download() take three argument as listed bellow syntax:


Syntax Download Method:




return response()->download($pathToFile, $name, $headers);




1) $pathToFile: path of force download file.

2) $name: assign new name of force download file.

3) $headers: set headers fop force download file.


As you see above syntax, you can just understand how to use download(), So here i will give you simple and basic example of download method.


Add Route

routes/web.php



Route::get('forceDonwload', 'HomeController@forceDonwload');




Add Controller Method

app/Http/Controllers/HomeController.php



<?php


namespace App\Http\Controllers;

use Illuminate\Http\Request;


class HomeController extends Controller

{


public function forceDonwload()

{

$pathToFile = public_path("myReportFile.pdf");

$name = time().'.pdf';

$headers = ['Content-Type: application/pdf'];


return response()->download($pathToFile, $name, $headers);

}

}




Make sure you have "myReportFile.pdf" file on your public directory for example.

As above simple example, you can run quick and check how it easy.

I hope you found best solution...

来自  https://hdtuto.com/article/laravel-55-force-download-file-using-response-helper

Response::download strange behavior


ndrbdo posted 3 years ago

Hello everyone!

First of all, thank you very much for your time. I'm having a problem with Response::download, and I hope someone would be so kind to help me.

I have the following:

    	Route::get('/download', function()
	{
		$file= public_path(). "/images/banner.jpg";
        $headers = array(
              'Content-Type: image/jpeg',
            );
        return Response::download($file, 'filename.jpg', $headers);
	});

It should download a .jpg image when I go to website.com/download. Thought, what I get is: Image.

Do you have any idea why?

Thanks so much for your help!

Saluki replied 3 years ago

Hi,

Just tested and it works perfect. So the problem -apparently- doesn't come from your code...

It's just a suggestion, but try the same code with another picture on another browser, and tell us what you then have as reponse...

Saluki replied 3 years ago

Try also to replace your $header with the following code:

$headers = array(
'Content-Type'=>'image/jpg',
);

Which version of Laravel are you using?

ndrbdo replied 3 years ago

Wow, you were fast! Ah ah... Thank you very much for your answer and time!

I tried with IE, Chrome and Firefox and with a new image (.png now) but still the same :( Might be PHP configuration, maybe?

ndrbdo replied 3 years ago

Laravel 4.2. Nope, nothing changes. Uff!

Saluki replied 3 years ago

Also not with the new $headers array?

Mmh, this doesn't look very good... Are you using an apache webserver?

ndrbdo replied 3 years ago

No, sadly still the same with the new $headers array.

Yes, I'm using Apache 2.2.29, and PHP 5.3.29. It's the first time this happens to me as well...

Saluki replied 3 years ago

Can you then check if your server has the mod_headers enabled (Apache module who can modify the HTTP headers). If it's not enabled, try this (on UNIX):

sudo a2enmod headers

(Must have administrator rights)

ndrbdo replied 3 years ago

Just asked my hosting provider about mod_headers. I'll write back as soon as they'll answer me! It should be in a few hours... I thank you again for your time!

ndrbdo replied 3 years ago

Saluki, mod_headers is ON already.

Saluki replied 3 years ago

Ok, if it isn't still solved, we will look at the problem from another point of view...

In firefox/chrome, go to the Developer Tools, then switch on the Network Tool and you will be able to see the HTTP response headers from the server... Can you post them?

Saluki replied 3 years ago

Your code works on my machine and I got this as HTTP response:

Response

ndrbdo replied 3 years ago

So strange! I get: HTTP/1.1 200 OK Date: Sun, 21 Dec 2014 13:45:16 GMT Server: LiteSpeed Connection: close Content-Type: text/html Vary: User-Agent Content-Length: 488613

I get a text/html instead of an image/jpeg... checking some PHP settings now... buoh..

ndrbdo replied 3 years ago

I'm sorry that I keep you spending your precious time here :(

Saluki replied 3 years ago

Sorry, just made some extra tests...

Try this one on your machine... It didn't use the Laravel functions, but still correctly download the picture:

Route::get('/down', function()
{
	$img = '../public/images/pic.jpg';
	header("Content-Type: application/force-download");
	header("Content-Length: " .(string)(filesize($img)) );

	echo file_get_contents($img);
	die();
});
ndrbdo replied 3 years ago

Uhm, I get the following error with your new code:

[2014-12-21 17:28:46] production.ERROR: exception 'ErrorException' with message 'Cannot modify header information - headers already sent by (output started at /home/user/laravel/app/routes.php:1)' in /home/user/laravel/app/routes.php:3139
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleError(2, 'Cannot modify h...', '/home/user/...', 3139, Array)
#1 /home/user/laravel/app/routes.php(3139): header('Content-Type: a...')
Saluki replied 3 years ago

Ok,

Can you print out your routes.php file? the problem is perhaps there...

The error you got indicates that output has already been sent to the browser and this should not be happen there.

ndrbdo replied 3 years ago

I'm sorry for my late answer. You're the man, Saluki! :D I deleted everything in my routes.php file except for the Response::download code, and it works!! So, there must be a problem somewhere in my 3147 lines of code, ah ah....

Thank you so much for your time!

ndrbdo replied 3 years ago

Apparently, "<?php" and "?>" tags were preceded by some spaces and tabs (I'm wondering why I didn't see that) which caused the header error. Grrrr... now it works just perfectly! :)

It was really kind of you to help me, Saluki.

Saluki replied 3 years ago

Haha, such a little error... Glad to see that your problem is finally solved :)

Happy coding...


来自  https://laravel.io/forum/12-21-2014-responsedownload-strange-behavior




Force downloading a file

PUBLISHED 3 YEARS AGO BY BERTSTANTON

I am having difficulty getting a file to force downloaded by Laravel.

I am generating a CSV file from a database, and writing that to a temporary file on the server. The CSV is being generated properly, and there are no issues writing the file to the server.

After this, I am trying to force download the file. I do so with: return Response::csv($tmp_file, 'output.csv');

At this point, the data from the CSV is just output to the browser. There is no file download prompt.

What can I do?

Best Answer(As Selected By BertStanton)
BertStanton

So... this is cute. Apparently I had an additional space above the <?php tag in a config file, which was sending output to the browser ahead of everything else. I figured this out by stripping out Laravel specific code from the method, and using the header() and readfile() functions.

Thanks for your help anyway.

FrancescoZaffaroni

Have you tried with Response::download();?

BertStanton

Hi, yes. My above post has a typo in it. It should be

return Response::download($tmp_file, 'output.csv');

That is what is not working. As I said, it just outputs everything to the browser.

FrancescoZaffaroni

Have you tried by manually setting the headers?

Devon
 Devon
3 years ago(53,640 XP)

Try this:

return Response::download($tmp_file, 'output.csv', ['Content-Type: text/cvs']);
BertStanton

Yes, I have also tried manually setting the headers. Also, I added "Content-type: force-download" (which I saw somewhere when I Googled this), and it didn't work.

Devon
 Devon
3 years ago(53,640 XP)

I didn't have a csv file so I just exported my migrations table, threw it in my app/storage folder , and set up the following route... Everything worked as expected, the file was automatically downloaded.

Route::get('/', function()
{
    $file = storage_path(). '\migrations.csv';
    return Response::download($file, 'test.csv', ['content-type' => 'text/cvs']);
});

I had to provided the 3rd parameter though, otherwise I was getting a fatal error:
Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?)

It then set the following response headers...

Content-Disposition:attachment; filename="test.csv"
Content-Length:137
Content-Transfer-Encoding:binary
Content-Type:text/cvs

Check your response headers and see what you're getting.

BertStanton

I implemented your code. This is what I get for my headers.

Date: Wed, 27 Aug 2014 17:53:22 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.6.0RC4 mod_ssl/2.2.26 OpenSSL/0.9.8y
Connection: Keep-Alive
X-Powered-By: PHP/5.6.0RC4
Transfer-Encoding: chunked
Keep-Alive: timeout=5, max=100
Content-Type: text/html; charset=UTF-8

200 OK

It still isn't working.

FrancescoZaffaroni

Try to add this to you headers settings.

Content-Disposition: attachment; filename="'.$file.'";

And can you show your code?

BertStanton

So... this is cute. Apparently I had an additional space above the <?php tag in a config file, which was sending output to the browser ahead of everything else. I figured this out by stripping out Laravel specific code from the method, and using the header() and readfile() functions.

Thanks for your help anyway.

FrancescoZaffaroni

Well, nice to hear that you have this sorted out.

Devon
 Devon
3 years ago(53,640 XP)

Haha! That'll do it. Glad you figured it out and thanks for letting us know what it was.
Also, Chrome's Developer Tools come in handy too when having to inspect response headers.

Please sign in or create an account to participate in this conversation.


来自  https://laracasts.com/discuss/channels/general-discussion/force-downloading-a-file

普通分类: