2017-05-03 21 views
3

我用laravel写入后端。并尝试从IONIC使用@angular/http调用api。API服务器始终响应“否”Access-Control-Allow-Origin'“

在后台服务器中,我已经在中间件和响应中添加了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()); 
     }); 
    }); 
    } 

当我打电话API与'Content-Type' : 'application/json'它总是响应误差。

XMLHttpRequest无法加载http://myurl.local/api/login。对 预检请求的响应未通过访问控制检查:否 “所请求的 资源上存在”Access-Control-Allow-Origin“标头。原因'http://localhost:8100'因此不允许 访问。

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

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

与邮递员很好。我真的尝试了很多方法来解决这个问题,但是我做不到。

有什么不对?

回答

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', '[email protected]'); 
    Route::options('/login', '[email protected]'); 
}); 

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

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

当我打电话API与'Content-Type' : 'application/json'它总是响应误差。

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

application/json content-type触发浏览器执行CORS预检OPTIONS请求。

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

随着邮递员很好。

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

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

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

+0

在中间件或控制器? – ThunderBirdsX3

+0

在你的中间件代码 – sideshowbarker

+0

可能是我做错了什么?它有同样的问题。 ($ request-> getMethod()==“OPTIONS”){ $ headers = [ 'Access-Control-Allow-Methods'=>'公共函数句柄($ request,Closure $ next) POST,GET', 'Access-Control-Allow-Headers'=>'Content-Type' ]; 返回响应:: make('OK',200,$ headers); } return $ next($ request); }' – ThunderBirdsX3