How to Solve CORS error in accessing laravel routes

Im very new to laravel applications.What im trying to do is developing an outlook web addon that uses the API written in laravel . The problem here is ,it produces the CORS error while accessing API's through outlook mail.

Error :

Access to XMLHttpRequest at 'https://test.com/api/test' from origin 'https://localhost:44377' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

What i have tried so far :

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

And finally end up with the same error.What should I do ?

Edit :

Why it automatically redirect the request to https instead of http .Where it went wrong ? The request url should be http://test.com/api/test ,not https://test.com/api/test

Thanks in advance !

Upvotes: 8

Views: 83552

Answers (10)

Don Ejeh
Don Ejeh

Reputation: 551

If you're hosting a React frontend and Laravel backend on a Plesk server and encountering a CORS policy issue (e.g., No 'Access-Control-Allow-Origin' header is present on the requested resource), here's a step-by-step solution that worked for me.

Access to fetch at 'https://apxxx.xxxx.ai/storage/speech/Sandra/2025-01-23-67921dafbbf39.wav' from origin 'https://xxxxx.ai' 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.

Steps to Resolve Navigate to Plesk Domain Settings:

Go to Websites & Domains in your Plesk dashboard. Select your domain (e.g., https://apis.example.com). Open Apache & nginx Settings. enter image description here Add Additional nginx Directives: In the Additional nginx directives section, add the following configuration to handle CORS for specific routes such as /storage or /uploads:

 location /storage {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    add_header 'Access-Control-Allow-Credentials' 'true';
}

location /uploads {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    add_header 'Access-Control-Allow-Credentials' 'true';
}

Save and Apply Changes:

Save the changes. Plesk will automatically apply the new directives to your server configuration.

Upvotes: 0

Morgan Codes
Morgan Codes

Reputation: 51

I spent two days troubleshooting this issue. The problem arises when you send headers data with AJAX or fetch requests. The browser immediately sends an OPTIONS request to your server, expecting a 200 status code in response. If this is not provided, the request is rejected, and your actual POST request will not be processed.

To resolve this, you need to ensure that your server responds correctly to OPTIONS requests. Below is an example of how to configure Nginx to handle OPTIONS requests and respond with a 200 status code. If you're using Apache instead of Nginx, you'll need to translate this configuration into .htaccess rules.

Plesk Panel (Apache and Nginx Settings):

config/cors.php:

<?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/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => false,

];

Laravel API Route (e.g., mysite.com/api/check-token):

Route::post('/check-token', [TokenController::class, 'checkToken']);

Nginx Configuration:

location /api/* {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' '*';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
    if ($request_method = OPTIONS ) {
        return 200;
    }
}

By configuring Nginx this way, you ensure that the server responds with a 200 status code to OPTIONS requests, allowing your POST requests to be processed correctly.

If you are using Apache, you will need to convert these settings into the equivalent .htaccess configuration.

I hope this helps!

Upvotes: -1

From Laravel 8 for CORS ORIGIN by default config/cors.php

If route prefix like bellow

Route::middleware('api')->prefix('api/v1/currency') 

then change path in config/cors.php

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

or if route like bellow in config/cors.php

Route::middleware('api')->prefix('currency/api/v1')

then change paths array to ('paths' => ['*'])

Upvotes: 0

Gustavo Marquez
Gustavo Marquez

Reputation: 499

This work for me:

php artisan make:middleware OwnCors

Code of the Middleware created:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class OwnCors
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        header("Access-Control-Allow-Origin: *");

        $headers = [
            'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers' => 'Content-Type, X-Auth-Token, Origin, Authorization'
        ];
        if ($request->getMethod() == "OPTIONS") {
            return response('OK')
                ->withHeaders($headers);
        }

        $response = $next($request);
        foreach ($headers as $key => $value)
            $response->header($key, $value);
        return $response;
    }
}

Add the middlware into your App\Http\Kernel.php

    protected $middleware = [
         \App\Http\Middleware\OwnCors::class,
         // Others middlewares
];

Upvotes: 7

Dale Ryan
Dale Ryan

Reputation: 843

For Laravel 8

In my case I added the origin that needs to access the resource.

// config/cors.php

// add a path to the resource here if you want it accessible to external origins
// for example no need to explicitly tell allowed origins
// what origins should gain access to api/* routes
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],

// explicitly tell which origins needs access to the resource
'allowed_origins' => ['*', 'https://mywebsite.com', 'http://mywebsite.com'],

// or use regex pattern, helpful if you want to grant
// access to origins with certain pattern (i.e. an origin under a subdomain etc.)
'allowed_origins_patterns' => ['/https?:\/\/mywebsite\.com\/?\z/'],

// no changes made below
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,

Also don't forget to run php artisan optimize in case you are caching the config.

Upvotes: 4

Praveen
Praveen

Reputation: 302

I am using Laravel 8

check config/cors.php

change paths array to * ('paths' => ['*'])

Upvotes: 7

Abolfazl Mohajeri
Abolfazl Mohajeri

Reputation: 1997

Try this way in your laravel app:

php artisan serve --host YOUR_LOCAL_IP

YOUR_LOCAL_IP is your ip that can access with ifconfig command in linux and ipconfig in windows.

Finally you should request to YOUR_LOCAL_IP:PORT/api

Upvotes: -4

Things you need to check if you are developing outlook addon :

  • Check whether you have included the domain name in manifest.xml ,in my case i need to include https://test.com to include in <AppDomain> tag.
  • Your domain should have ssl certificate .(ie) outlook allows you to request only through https .

And follow this answer as well : middleware to solve cors

Upvotes: 0

Odin Thunder
Odin Thunder

Reputation: 3547

I had the same problem, solved it by Middleware

Define your custom middleware

//App\Http\Middleware;

public function handle($request, Closure $next)
{
    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', '*')
        ->header('Access-Control-Allow-Credentials', true)
        ->header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type,X-Token-Auth,Authorization')
        ->header('Accept', 'application/json');
}

Than just register yours Middleware, local (for specific route/routes) or global.

How to register Middleware

Notice! Some old brovsers do not support '*' logic

Upvotes: 9

Syahnur Nizam
Syahnur Nizam

Reputation: 91

If you are using Laravel 7.0, it already has CORS functionality built in

Upvotes: -3

Related Questions