API Server always responds "No" Access-Control-Allow-Origin "

I am writing back end with laravel. And try calling api from IONIC use @angular/http

.

In the back-end serer, I already add Access-Control-Allow-Origin

in middleware and answer.

Middleware.

return $next($request)
      ->header('Access-Control-Allow-Origin', '*')
      ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
      ->header('Access-Control-Allow-Credentials', true)
      ->header('Access-Control-Allow-Headers', 'Content-Type')
      ->header('Vary', 'Origin');

      

Answer.

return response($data, 200)
      ->withHeaders([
        'Content-Type' => 'application/json',
        'Access-Control-Allow-Origin' => '*',
        'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE',
        'Access-Control-Allow-Credentials' => true,
        'Access-Control-Allow-Headers' => 'Content-Type',
        'Vary' => 'Origin',
      ]);

      

ION

  url: any = 'http://myurl.local/api/';

  headers = new Headers(
  {
    'Accept' : 'application/json',
    'Content-Type' : 'application/json',
    'Access-Control-Request-Methods' : 'POST'
  });
  options = new RequestOptions({ headers: this.headers });

login(username, password) {
    let data = JSON.stringify({
      username : username,
      password : password
    });
    let fullUrl = this.url+'login';

    return new Promise((resolve, reject) => {
      this.http.post(fullUrl, data, this.options)
      .toPromise()
      .then((response) =>
      {
        console.log('API Response : ', response);
        resolve(response.json());
      })
      .catch((error) =>
      {
        console.error('API Error : ', error.toString());
        reject(error.json());
      });
    });
  }

      

When I call the api with 'Content-Type' : 'application/json'

, it is always responsible for the error.

XMLHttpRequest cannot load http: //myurl.local/api/login . Preflight Request Response Fails Access Control Check: None The Access-Control-Allow-Origin header is present on the requested resource. Origin ' http: // localhost: 8100 ' is therefore not allowed access.

But if I change 'Content-Type'

to 'application/x-www-form-urlencoded'

. I didn't have any errors.

But when I try to see the entrance $request->all()

. Received data - '{"username":"XXXXXXXXXX","password":"XXXXXXXXXX"}' => NULL

.

The postman is all right. I am really trying a lot to solve this problem, but I cannot.

What's wrong?

+3


source to share


2 answers


Yeahhhh !!! Finally I can work it out. God damn it.

In middleware.

public function handle($request, Closure $next)
  {
    if ($request->getMethod() == "OPTIONS") {
      return response(['OK'], 200)
        ->withHeaders([
          'Access-Control-Allow-Origin' => '*',
          'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE',
          'Access-Control-Allow-Credentials' => true,
          'Access-Control-Allow-Headers' => 'Authorization, Content-Type',
        ]);
    }

    return $next($request)
    ->header('Access-Control-Allow-Origin', '*')
    ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
    ->header('Access-Control-Allow-Credentials', true)
    ->header('Access-Control-Allow-Headers', 'Authorization, Content-Type');

  }

      

The header changes IONIC to.



headers = new Headers(
{
  'Content-Type' : 'application/json'
});

      

And it won't work until you add a route options

. (In my case, because I am not using Route::resource

)

Route::group(['middleware' => 'AddHeader'], function()
{
  Route::post('/login', 'LoginController@index');
  Route::options('/login', 'LoginController@index');
});

      

PS. I have some logic in function index()

I am trying to use __construct()

. But it doesn't work.

+4


source


In your Laravel code that handles requests, you need to add handling for requests OPTIONS

:

if ($request->getMethod() == "OPTIONS") {
    $headers = [
        'Access-Control-Allow-Origin' => '*'
        'Access-Control-Allow-Methods'=> 'POST, GET',
        'Access-Control-Allow-Headers'=> 'Content-Type'
    ];
    return Response::make('OK', 200, $headers);
}

      

When I call the api with 'Content-Type' : 'application/json'

, it is always responsible for the error.

But if I change 'Content-Type'

to 'application/x-www-form-urlencoded'

. I didn't have any errors.

application/json

content type triggers browsers to perform CORS previews OPTIONS

.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests has more details.



The postman is fine.

Postman is free to send cross-origin requests without limitation. But browsers will not allow your external JavaScript code to access the response from a cross-origin request, unless the response indicates that the server to which the request is sent is the choice to accept cross-origin requests.

And if your request is the one that triggers browsers to request the OPTIONS

CORS preflight request , the server that the request is sent to must be configured to respond correctly to the request OPTIONS

. This is why you need to add additional processing to your Laravel code for requests OPTIONS

.

If the server does not respond to the preview OPTIONS

correctly, the browser will stop there and never be able to fulfill the request POST

you are actually trying to send.

+1


source







All Articles