skip to Main Content

I am trying to access a log file URL from Angular, but it is showing the following error:

Access to XMLHttpRequest at 'https://myurl.com/storage/rmlogs/MyFileNameDetail.log' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

All the API requests are working perfectly fine and the error is only for the file requests. I have my files stored inside rmlogs directory which is in storage/app/public/rmlogs and it is linked to the public folder.

The API codebase is Laravel and the files are stored in storage directory. I am able to access the file through browser as well as Postman. As the URL is publicly available, it doesn’t need Authentication Token, which I am passing for other API requests.

I have the cors.php configuration file as follows:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['api/*'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,

];

and has a Cors.php middleware as given below:

<?php

namespace AppHttpMiddleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    }
}

3

Answers


  1. Via this blog:

    there are packages available that allow for adding CORS headers to responses sent from a Laravel API. They do so by applying middleware to all of the API’s routes. However, such middleware is not applied to the public directory, and that is often the storage location for resources such as user avatar images. Therefore, when those resources are returned to the browser, they do not have the necessary CORS headers applied.

    So you need to apply the headers using some other method. This is probably most easily done using your HTTP server’s configuration files.

    You’ve tagged this so you can set:

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

    In your configuration file.

    For example:

    <Location "/storage/rmlogs/">
        Header set Access-Control-Allow-Origin "*"
    </Location>
    

    You could also put the Header directive in a .htaccess file, but this isn’t recommended:

    You should avoid using .htaccess files completely if you have access to httpd main server config file. Using .htaccess files slows down your Apache http server. Any directive that you can include in a .htaccess file is better set in a Directory block, as it will have the same effect with better performance.

    If you are on shared hosting, you might not have a choice though.

    Login or Signup to reply.
  2. You are accessing a file in a non-standard storage directory. It might be that your request is not filtered via laravel because it resides in a storage directory, which often permits direct access.

    In that case it’s handled by the webserver.
    These are the storage access rules that get rewritten to the laravel controller in my installation via htaccess.

    RewriteRule ^storage/cms/.* index.php [L,NC]
    RewriteRule ^storage/logs/.* index.php [L,NC]
    RewriteRule ^storage/framework/.* index.php [L,NC]
    RewriteRule ^storage/temp/protected/.* index.php [L,NC]
    RewriteRule ^storage/app/uploads/protected/.* index.php [L,NC]
    

    As you can see, storage/rmlogs is not part of it, so it’s handled by the webserver if i’d try to access a rmlogs directory in storage.

    To solve this you could make a .htaccess rule to add it if you run on apache, or a nginx directive if you run nginx.

    RewriteRule ^storage/rmlogs/.* index.php [L,NC]
    
    Login or Signup to reply.
  3. Anyone looking for the solution for apache, here is the ultimate solution according to mozilla’s own documentation.
    https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image

    <IfModule mod_setenvif.c>
      <IfModule mod_headers.c>
        <FilesMatch ".(avifs?|bmp|cur|gif|ico|jpe?g|jxl|a?png|svgz?|webp)$">
          SetEnvIf Origin ":" IS_CORS
          Header set Access-Control-Allow-Origin "*" env=IS_CORS
        </FilesMatch>
      </IfModule>
    </IfModule>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search