2

I followed the instructions from this post and applied the following to my Laravel 5.4 backend which is a REST API for my Angular web client.

First I installed the Cors middleware

php artisan make:middleware Cors

I went to app/Http/Middleware/Cors.php and added the two headers:

public function handle($request, Closure $next)
{
    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}

I added 'cors' => \App\Http\Middleware\Cors::class to $routeMiddleware in app/Http/Kernel.php.

protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'cors' => \App\Http\Middleware\Cors::class,
];

and finally added middleware('cors') to the api routes mapping as such:

protected function mapApiRoutes()
{
    Route::prefix('api')
         ->middleware('api')
         ->middleware('cors')
         ->namespace($this->namespace)
         ->group(base_path('routes/api.php'));
}

However, only my GET request is working:

onSubmit() {
  // Fails: "No 'Access-Control-Allow-Origin' header is present.."
  console.log('Submit ..');
  this.http.post('http://localhost:8080/api/register', JSON.stringify(this.registerForm.value))
    .subscribe(
        data => alert('yay'),
        err => alert(err.error.message)
    );
}

onCancel() {
  // Is working..
  console.log('Cancel ..');
  this.http.get('http://localhost:8080/api/helloworld')
    .subscribe(
      data => alert(data),
      err => alert('error')
    );
}

Any idea why only the GET request works but not the POST?


This is how I create the routes in the api.php file:

Route::get('/helloworld', function (Request $request) {
    return ['Hello World!'];
});

Route::post('/register', function (Request $request) {
    // dd($request->input("email"));
    return ['register'];
});

Response for the GET call:

Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Cache-Control:no-cache, private
Connection:close
Content-Type:application/json
Date:Sat, 28 Oct 2017 15:14:27 GMT
Host:localhost:8080
X-Powered-By:PHP/7.0.22-0ubuntu0.16.04.1

Response for the POST call:

Allow:POST
Cache-Control:no-cache, private
Connection:close
Content-Type:text/html; charset=UTF-8
Date:Sat, 28 Oct 2017 15:10:30 GMT
Host:localhost:8080
X-Powered-By:PHP/7.0.22-0ubuntu0.16.04.1

as you can see, for some reason the headers are not set in the POST response.

Stefan Falk
  • 23,898
  • 50
  • 191
  • 378

2 Answers2

0

I thinking also you need to add this

->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');

  • Unfortunately this does not help. For some reasons the headers are missing in the POST response completely. – Stefan Falk Oct 28 '17 at 15:22
  • In api.php Which method you called with controller method? Is it POST method ? – Abu Jafar Md. Salah Oct 28 '17 at 15:28
  • Yes, I added the two routes to my question. I'm calling `Route::get` and `Route::post` for those calls separately. – Stefan Falk Oct 28 '17 at 15:31
  • So, Can you block Route::get and test with POST and have you tested with Postman ? – Abu Jafar Md. Salah Oct 28 '17 at 15:34
  • What do you mean by block Route:get? I'm not using Postman but a Chrome plugin "Advanced REST Client" to test calls - if I run the request there, the headers are present.. thus I thought it's a browser thing but the POST won't work whether in Chrome nor in Firefox. – Stefan Falk Oct 28 '17 at 15:39
  • I mean now you are using same URL for GET and POST Route, So I am asking you php block /* */ in Route::get and test. – Abu Jafar Md. Salah Oct 28 '17 at 15:51
  • No, I used two different URLs for those requests. – Stefan Falk Oct 28 '17 at 16:44
  • Can you add this method I added header in this : onSubmit() { // Fails: "No 'Access-Control-Allow-Origin' header is present.." console.log('Submit ..'); const headers = new Headers({'Content-Type': 'application/json'}); this.http.post('http://localhost:8080/api/register', JSON.stringify(this.registerForm.value), {headers: headers}) .subscribe( data => alert('yay'), err => alert(err.error.message) ); } – Abu Jafar Md. Salah Oct 29 '17 at 03:12
  • 1
    Hi! I was able to make it work - idk why exactly it was necessary to do that but after installing [laravel-cors](https://github.com/barryvdh/laravel-cors) things started working. Still, thank you very much for trying to help me! – Stefan Falk Oct 29 '17 at 08:42
0

when working with laravel, often, that error doesnt mean its from the post request, nor from your CORS.php or KERNEL. it can mean a lot of things even database column none existence, and due to the fact the request is coming from another server, laravel tries to hide the specific error in chrome, throwing that error. to know the specific error and debug it, you should use postman, to trigger that route, and send that request, postman will give you the right error message. but also replace your cors.php with this instead

$response = $next($request);
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers',' Origin, Content-Type, Accept, Authorization, X-Request-With, X-Auth-Token');
$response->headers->set('Access-Control-Allow-Credentials',' true');
return $response;
MartenCatcher
  • 2,713
  • 8
  • 26
  • 39
Buchi
  • 368
  • 1
  • 4
  • 16