Laravel CORS处理公用文件夹中的图像文件时出现问题?

时间:2019-10-22 01:24:21

标签: laravel nginx cors laravel-valet

因此,我将图像存储在名为“ 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本地主机而不是project.test发出请求时,出现了同样的错误。我还要注意我正在使用代客服务。

希望有人可以为此提供帮助。

5 个答案:

答案 0 :(得分:1)

使用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,        
    ];

答案 1 :(得分:1)

我将此行放在.htaccess文件中:

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

对我有用。

答案 2 :(得分:0)

我在进行以下设置时遇到了类似的问题:

  • 已启用的CorsMiddleware,它应该可以处理不同的获取,发布,放置等路线。

  • 在lumen项目的“公共”文件夹中的images文件夹。尽管CorsMiddleware适用于路线,但访问images文件夹中的文件将导致CORS错误。

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

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

另一方面,将同一行添加到公用文件夹的.htaccess无效。这使allow-origin头设置为两次(由CorsMiddleware和.htaccess设置)。因此,在我的案例中,关键是在子文件夹中添加自己的.htaccess。

答案 3 :(得分:0)

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

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

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

快乐编码!

答案 4 :(得分:0)

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

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

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