【问题标题】:BinaryFileResponse in Laravel undefinedLaravel 中的 BinaryFileResponse 未定义
【发布时间】:2022-03-24 14:06:27
【问题描述】:

我遇到了以下问题: 我想在路线 /getImage/{id} 上返回一个图像 函数如下所示:

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

当我这样做时,它会返回给我:

FatalErrorException in HandleCors.php line 18:
Call to undefined method Symfony\Component\HttpFoundation\BinaryFileResponse::header()

我在控制器的开头有use Response;。 我不认为 HandleCors.php 是问题,但无论如何:

<?php namespace App\Http\Middleware;
use Closure;

use Illuminate\Contracts\Routing\Middleware;
use Illuminate\Http\Response;

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');
     }
}

我实际上不知道为什么会发生这种情况,因为它与 Laravel 文档中描述的完全一样。 当我收到错误时,我已经更新了 Laravel,但这并没有解决它。

【问题讨论】:

  • 你使用的是哪个版本的 Laravel?
  • 版本 5.0.21 更新后 5.0.14 之前
  • 你应该使用return response()-&gt;download(public_path("images/'.$image-&gt;filename"));或类似的东西。
  • 好吧,错误似乎很正确:您不能设置 $request 的标头,只能设置 Response..
  • 还有什么解决办法,因为我现在不知道该怎么办?

标签: php laravel


【解决方案1】:

问题是您在没有该功能的Response 对象(Symfony\Component\HttpFoundation\BinaryFileResponse 类)上调用-&gt;header()-&gt;header() 函数是 Laravel 的 Response class 使用的 part of a trait,而不是基本的 Symfony 响应。

幸运的是,您可以访问headers 属性,因此您可以这样做:

$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;

【讨论】:

  • 我像你说的那样改变了它,它确实有帮助,但现在在第二行出现“尝试获取非对象的属性”错误。
  • @Sebi55 嗯,我的错。显然-&gt;set() 是不可链接的。
  • 是的,这也是我的想法。任何其他想法如何修复中间件以使用 BinaryFileResponse?
  • 我不明白你的回答,但它对我有用。 :)
  • @treeface,谢谢,它对我有用,但在为每个语句添加分号之前它不起作用。您能否为每个语句添加分号?对以后的用户会有帮助
【解决方案2】:

您可能希望通过检查返回的Closure 中是否存在header 方法来为file 下载请求排除标头或设置不同的标头。

文件下载请求通常在Closure 中省略header 方法。


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;
    
}

如果您需要为file 请求设置标头(如其他答案所建议的那样)$handle-&gt;headers-&gt;set() 可以在else 条件中使用:


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;
    
}

【讨论】:

    【解决方案3】:

    如果您创建了中间件来防止回溯历史,现在当您想要下载文件时,您会收到以下错误:调用未定义的方法 Symfony\Component\HttpFoundation\BinaryFileResponse::header()

    因此,您应该将您的 PreventBackHistory 文件编辑为:

    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;       
        }
    

    在您创建的 CORS.php 文件中,您应该放入以下代码行:

     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;
         }
    

    【讨论】:

      【解决方案4】:

      这对我有用!我希望它会有所帮助。

      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;
      }
      

      【讨论】:

        猜你喜欢
        • 2018-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-21
        • 2018-01-08
        • 2021-01-07
        相关资源
        最近更新 更多