【问题标题】:Laravel CORS Issue when dealing with image files inside public folder?处理公用文件夹中的图像文件时 Laravel CORS 问题?
【发布时间】:2020-02-18 02:45:47
【问题描述】:

因此,我将图像存储在名为“images”的子目录中的公用文件夹中,并尝试向其中一个发出请求。

但是,我经常收到错误消息;

Access to fetch at 'http://project.test/images/4obrUhRprw6CXSHsHEGEf4Gje2baKoiS7PQJvS4F.jpeg' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

我认为这是因为我使用 VueJS 作为 SPA 前端,就好像我前往 project.test 并提出请求,它工作正常。

我正在使用 laravel-cors 但经过一些研究,我发现这显然不适用于公共文件夹,所以我尝试在公共文件夹中使用 .htaccess 文件,这就是我有;

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://([^.]+\.)?(localhost:8080)$" AccessControlAllowOrigin=$0$1
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header set Access-Control-Allow-Credentials true
    </IfModule>


    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

但是,它似乎仍然不起作用,当我从我的 Vue localhost 而不是 project.test 发出请求时,我得到了同样的错误。我还应该注意我正在使用 Valet。

希望有人可以提供一些帮助。

【问题讨论】:

  • 响应的 HTTP 状态码是什么?您可以使用浏览器开发工具中的网络窗格进行检查。是 4xx 还是 5xx 错误而不是 200 OK 成功响应?
  • @sideshowbarker 图片请求的实际响应居然是200,这更让我困惑。
  • 你有没有设法解决这个问题?
  • 这里有什么解决办法。我遇到了同样的问题。

标签: laravel nginx cors laravel-valet


【解决方案1】:

我把这行放在.htaccess 文件中:

Header always set Access-Control-Allow-Origin "*"

它对我有用。

【讨论】:

    【解决方案2】:

    使用 CORS 添加中间件

    <?php
    namespace App\Http\Middleware;
    
    use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
    use Closure;
    use Illuminate\Support\Facades\Response;
    
    class CORS extends Middleware {
    
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {            
            $origin = $request->header('origin');
            $origin = $origin ?? '*';
    
            // ALLOW OPTIONS METHOD
            $headers = [
                'Access-Control-Allow-Origin' => $origin,
                'Access-Control-Allow-Methods'=> 'GET, POST, DELETE, PUT, OPTIONS, HEAD, PATCH',
                'Access-Control-Allow-Headers'=> 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Set-Cookie',
                'Access-Control-Allow-Credentials'=> 'true'
            ];
    
            if($request->getMethod() == "OPTIONS") {
                // The client-side application can set only headers allowed in Access-Control-Allow-Headers
                return Response::make('OK', 200, $headers);
            }
    
            $response = $next($request);
    
            foreach($headers as $key => $value) {
                $response->header($key, $value);
            }
            return $response;
        }
    
    }
    

    文件app/Http/Kernel.php

    protected $middleware = [
            // Your middleware...
    
            \App\Http\Middleware\CORS::class,        
        ];
    

    【讨论】:

    • 我已经在使用 laravel-cors 包,它基本上可以做到这一点。根据我所做的一些研究,公共文件夹不受中间件的影响。
    【解决方案3】:

    我在以下设置中遇到了类似的问题:

    • 一个已启用的 CorsMiddleware,它按照预期的方式处理不同的 get、post、put 等路由。

    • lumen 项目的“公共”文件夹内的图像文件夹。访问 images 文件夹中的文件会导致 CORS 错误,尽管 CorsMiddleware 适用于路由。

    对我有用的解决方案: 根据@Hadeel Mostafa 的建议,我在 public/images 文件夹中添加了一个 .htaccess 文件,其中包含以下行:

    Header always set Access-Control-Allow-Origin "*"
    

    另一方面,将同一行添加到公用文件夹的 .htaccess 中不起作用。它导致 allow-origin 标头被设置两次(通过 CorsMiddleware 和 .htaccess)。所以在我的例子中,关键是向子文件夹添加一个自己的 .htaccess。

    【讨论】:

      【解决方案4】:

      在 bootstrap\app.php 文件的顶部添加这些行。实际上,中间件仅适用于并非所有请求中的路由,因此允许它在应用程序被引导的位置添加所有代码。

      header('Access-Control-Allow-Origin: *');
      header('Access-Control-Allow-Methods: *');
      header('Access-Control-Allow-Headers: *');
      

      测试必须刷新浏览器缓存或进入隐身模式,因为浏览器会从缓存中获取响应。

      【讨论】:

        【解决方案5】:

        更简单的解决方案是使用 fruitcake/laravel-cors 并在您的 cors.php 配置文件中编辑此行:

            'paths' => ['api/*', 'sanctum/csrf-cookie'],
        

            'paths' => ['api/*', 'sanctum/csrf-cookie', '/images/*'],
        

        编码愉快!

        【讨论】:

          猜你喜欢
          • 2017-03-23
          • 2020-04-01
          • 2021-02-16
          • 2014-12-04
          • 2017-02-03
          • 2017-06-18
          • 2013-06-03
          • 1970-01-01
          • 2015-02-08
          相关资源
          最近更新 更多