BinaryFileResponse in Laravel undefined

Posted on

BinaryFileResponse in Laravel undefined – Here in this article, we will share some of the most common and frequently asked about PHP problem in programming with detailed answers and code samples. There’s nothing quite so frustrating as being faced with PHP errors and being unable to figure out what is preventing your website from functioning as it should like php and laravel . If you have an existing PHP-based website or application that is experiencing performance issues, let’s get thinking about BinaryFileResponse in Laravel undefined.

I have got the following problem:
I want to return an Image on the route /getImage/{id}
The function looks like this:

public function getImage($id){
   $image = Image::find($id);
   return response()->download('/srv/www/example.com/api/public/images/'.$image->filename);
}

When I do this it returns me this:

FatalErrorException in HandleCors.php line 18:
Call to undefined method SymfonyComponentHttpFoundationBinaryFileResponse::header()

I have got use Response; at the beginning of the controller.
I dont think that the HandleCors.php is the problem but anyway:

<?php namespace AppHttpMiddleware;
use Closure;

use IlluminateContractsRoutingMiddleware;
use IlluminateHttpResponse;

class CORS implements Middleware {

public function handle($request, Closure $next)
{
      return $next($request)->header('Access-Control-Allow-Origin' , '*')
            ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE')
            ->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
     }
}

I actually dont know why this happens since it is exactly like it is described in the Laravel Docs.
I have updated Laravel when I got the error but this did not fix it.

Solution :

The problem is that you’re calling ->header() on a Response object that doesn’t have that function (the SymfonyComponentHttpFoundationBinaryFileResponse class). The ->header() function is part of a trait that is used by Laravel’s Response class, not the base Symfony Response.

Fortunately, you have access to the headers property, so you can do this:

$response = $next($request);

$response->headers->set('Access-Control-Allow-Origin' , '*');
$response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');

return $response;

You may want to exclude headers or set different headers for file download requests by checking the header method exists in the returned Closure.

File download requests typically have the header method omitted from Closure.


public function handle($request, Closure $next)
{
    $handle = $next($request);

    if(method_exists($handle, 'header'))
    {
        $handle->header('Access-Control-Allow-Origin' , '*')
               ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE')
               ->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
    }

    return $handle;
    
}

If you need to set headers for a file request (as other answer suggested) $handle->headers->set() can be used in an else condition:


public function handle($request, Closure $next)
{
    $handle = $next($request);

    if(method_exists($handle, 'header'))
    {
        // Standard HTTP request.

        $handle->header('Access-Control-Allow-Origin' , '*');

        return $handle;
    }

    // Download Request?

    $handle->headers->set('Some-Other-Header' , 'value')

    return $handle;
    
}

If you have created middleware to prevent back history and now when you want to download a file, you are getting the following error: Call to undefined method SymfonyComponentHttpFoundationBinaryFileResponse::header()

You should therefore edit yout PreventBackHistory file to:

public function handle($request, Closure $next)
    {
 
        $headers = [
            'Cache-Control'      => 'nocache, no-store, max-age=0, must-revalidate',
            'Pragma'     => 'no-cache',
            'Expires' => 'Sun, 02 Jan 1990 00:00:00 GMT'
        ];
        $response = $next($request);
        foreach($headers as $key => $value) {
            $response->headers->set($key, $value);
        }
 
        return $response;       
    }

Inside your CORS.php file that you have created you should put the following lines of code:

 public function handle($request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('Access-Control-Allow-Origin' , '*');
        $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
        $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
        
        return $response;
     }

This worked for me! I hope it will be helpful.

public function handle($request, Closure $next)
{
        
        $response = $next($request);
        $headers = [
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Methods' => 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS',
            'Access-Control-Allow-Headers' => '*',
        ];

        foreach($headers as $key => $value) {
            $response->headers->set($key, $value);
        }

        return $response;
}

Leave a Reply

Your email address will not be published. Required fields are marked *