API服务器始终响应" No' Access-Control-Allow-Origin'"

时间:2017-05-03 04:01:50

标签: laravel ionic-framework cors laravel-5.4 ionic3

我用laravel写后端。并尝试使用IONIC来调用api @angular/http

在后端服务器中,我已经在中间件和响应中添加了Access-Control-Allow-Origin

中间件。

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');

响应。

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',
      ]);

离子

  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());
      });
    });
  }

当我使用'Content-Type' : 'application/json'调用api时,它总是响应错误。

  

XMLHttpRequest无法加载http://myurl.local/api/login。回应   预检请求未通过访问控制检查:否   '访问控制允许来源'标题出现在请求的上   资源。起源' http://localhost:8100'因此是不允许的   访问。

但如果我将'Content-Type'更改为'application/x-www-form-urlencoded'。我没有收到任何错误。

但是当我试图看到输入$request->all()时。我得到的数据是'{"username":"XXXXXXXXXX","password":"XXXXXXXXXX"}' => NULL

邮差很好。我真的尝试了很多方法来解决这个问题,但我不能。

有什么不对?

2 个答案:

答案 0 :(得分:4)

Yeahhhh !!!最后,我可以解决这个问题。该死的。

在中间件中。

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');

  }

在IONIC中更改标题为。

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

在添加options路由后,它才会生效。 (就我而言,因为我没有使用Route::resource

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

PS。我在function index()中有一些逻辑,我尝试使用__construct()。但它不起作用。

答案 1 :(得分:1)

在处理请求的Laravel代码中,您需要为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);
}
  

当我使用'Content-Type' : 'application/json'调用api时,它总是响应错误。

     

但如果我将'Content-Type'更改为'application/x-www-form-urlencoded'。我没有收到任何错误。

application/json内容类型触发浏览器执行CORS预检OPTIONS请求。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests有更多详情。

  

邮差很好。

邮差可以不受限制地自由地提出跨域请求。但浏览器不允许您的前端JavaScript代码访问来自跨源请求的响应,除非响应指示发送请求的服务器正在选择接收跨源请求。

如果您的请求是触发浏览器执行CORS预检OPTIONS请求的请求,则请求发送到的服务器必须配置为以正确的方式响应OPTIONS请求。这就是为什么您需要在Laravel代码中为OPTIONS请求添加额外处理。

如果服务器没有以正确的方式响应OPTIONS预检,那么浏览器将停在那里,并且永远无法执行您实际尝试发送的POST请求。< / p>