skip to Main Content

I’ve configured my laravel 11 application to handle cors using the following cors.php file in the config dir

<?php

return [

    'paths' => ['*'],

    'allowed_methods' => ['GET, POST, PUT, OPTIONS'],

    'allowed_origins' => ['http://localhost:8082'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['Origin, Content-Type, X-Auth-Token , Cookie'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,

];

my local server at 8082 is trying to access the laravel server at 8000 but im getting cors issue from the browser

index.html:1 Access to XMLHttpRequest at 'http://localhost:8000/game/server?sessionId=475826' from origin 'http://localhost:8082' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

what i dont understand is that it seems to be working, the OPTIONS request is getting 204 response and i can see the headers on the dev tools

enter image description here

enter image description here

the actual POST request is missing these headers

enter image description here

and i can actually debug the response method – meaning that the request is indeed getting to the server.

on postman i get a normal response

2

Answers


  1. From your screenshot above, your OPTIONS call is returning the Access-Control-Allow-Origin header, but your actual POST call is not.

    I encountered a similar problem when using laravel-mpdf trying to stream a PDF file using

    return $pdf->stream('file.pdf');
    

    I realised that calling the above stream function on my pdf object was bypassing Laravel’s HandleCors middleware.

    I wrapped the pdf stream function in a Laravel response function as below and it worked, applying the HandleCors middleware and adding the required headers:

    return response()->streamDownload(function () use ($pdf) {
        $pdf->stream('file.pdf');
    }, 'file.pdf');
    

    I’m guessing that your POST function is not using one of Laravel’s responses so maybe try to use one of them?

    Or the alternative dirty hacky way would be to add header functions right before your return statement, something like:

    header('Access-Control-Allow-Origin: http://localhost:8082');
    header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
    header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token , Cookie');
    
    //your return
    return $something;
    
    Login or Signup to reply.
  2. Creating your own middleware CORS file and registering it in bootstrap/app.php is one approach that works, but it requires additional and unnecessary work.

    I will leave my working example here for anyone else facing this CORS issue in Laravel 11.

    Remember that Laravel 11 does not have the AppHttpkernel.php file any longer, so you only need to configure your configcors.php file as usual:

    'paths' => ['*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['http://localhost:3000', 'http://user-client'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
    

    Then, I defined a route for my client App (in React 18) to connect to my backend service:

    Route::get('/getData', [sseController::class, 'index']);
    

    Finally, wrote the controller:

    namespace AppHttpControllers;
    
    use SymfonyComponentHttpFoundationStreamedResponse;
    
    final class sseController extends Controller {
    
       public function index() {
          // Create a response object
          $response = new StreamedResponse(function () {
             $data = json_encode(['message' => 'This is a message']);
    
             echo "data: $datann";
    
             // Flush the output buffer
             ob_flush();
             flush();
          });
    
          // Set the right headers for SSE.
          $response->headers->set('Content-Type', 'text/event-stream');
          $response->headers->set('Cache-Control', 'no-cache');
          $response->headers->set('Connection', 'keep-alive');
    
          return $response;
       }
       
    }
    

    The Symfony StreamedResponse class is important here to wrap the content, to send to the client App, in some sort of Response object that can be returned by the method.

    This is my client App:

    import { useState } from 'react'
    import './App.css'
    
    function App() {
       const [serverData, setServerData] = useState('');
    
       // Open a connection to the server to receive events from it...
       const eventSource = new EventSource("http://user-svc/getData", { withCredentials: true });
    
       // Event handler to receive messages
       eventSource.onmessage = (event) => {
          setServerData(event.data);
       };
    
    
       return (
          <div className="App">
             <header className="App-header">
                <div>
                   <p>Data received from server event:</p>
                   <div>{ serverData }</div>
                </div>
             </header>
          </div>
       );
    }
    
    export default App;
    

    The response can be parsed to show the different JSON fields independently in the UI, but this is only a simple example that can be used as a base for a more complex task.

    Hope this helps someone.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search