Laravel 解决添加CROS中间件后出现Storage私有文件无法访问与下载
问题描述
添加了跨域中间件后,发现文件预览出现了报错,报错信息如下:
Symfony\Component\Debug\Exception\FatalThrowableError
Call to undefined method Symfony\Component\HttpFoundation\BinaryFileResponse::header()
问题原因
排查后发现中间件设置了请求头后会出现这个问题,这是因为Laravel响应请求的实现的类不一样,需要在中间件调用对应的方法设置请求头。
解决方法
引用对应的类
use Illuminate\Http\Response as IlluminateResponse;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
根据类调用不同的返回头设置方法
if ($response instanceof IlluminateResponse) {
$response->header($k, $v);
}
if ($response instanceof SymfonyResponse) {
$response->headers->set($k, $v);
}
下面是我的跨域中间件,可以参考参考。
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Response as IlluminateResponse;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
/**
* 跨域
*
* @author Wenhsing <wenhsing@qq.com>
*/
class CORSMiddleware
{
// 请求头
protected $headers = [
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Max-Age' => 1800,
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
];
/**
* Handle an incoming request.
*
* @author Wenhsing <wenhsing@qq.com>
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
if (! isset($this->headers['Access-Control-Allow-Origin'])) {
$this->setAllowHeaders();
$origin = $request->header('Origin') ?: '';
$domain = config()->get('cors.domain');
if ($origin && ('' === $domain || strpos($origin, $domain))) {
$this->headers['Access-Control-Allow-Origin'] = $origin;
} else {
$this->headers['Access-Control-Allow-Origin'] = '*';
}
foreach ($this->headers as $k => $v) {
if ($response instanceof IlluminateResponse) {
$response->header($k, $v);
}
if ($response instanceof SymfonyResponse) {
$response->headers->set($k, $v);
}
}
}
return $response;
}
/**
* 设置请求头部允许字段
*
* @author Wenhsing <wenhsing@qq.com>
* @return void
*/
public function setAllowHeaders()
{
$headerArr = [
'Authorization',
'Content-Type',
'If-Match',
'If-Modified-Since',
'If-None-Match',
'If-Unmodified-Since',
'X-CSRF-TOKEN',
'X-Requested-With',
'lang',
'token',
'X-Token',
];
$headers = implode(', ', $headerArr);
$this->headers['Access-Control-Allow-Headers'] = $headers;
}
}