我一直在寻找解决这个问题的方法。
我有一个带有Laravel 4后端实现的AngularJS Web应用程序,如下所示:
http://app.mydomain.io/ = AngularJS web app
http://api.mydomain.io/ = Laravel Back-end
在Laravel的routes.php文件中,我有以下PHP代码来设置Access-Control标头:
header('Access-Control-Allow-Origin: http://app.mydomain.io');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
我还有一个登录请求的路由设置,如下所示:
Route::post('/login', function()
{
$email = Input::get('email');
$password = Input::get('password');
if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
return "Success!";
} else {
return "Fail!";
}
});
在AngularJS中,我有一个AuthService,如下所示:
app.factory('AuthService', ['$resource', '$q', '$cookieStore', function($resource, $q, $cookieStore) {
var user = null;
var Service = $resource('//api.mydomain.io/login/', {}, {});
return {
login: function(email, password) {
var deferred = $q.defer();
Service.save({email: email, password: password}, function(response) {
$cookieStore.put('user', JSON.stringify(response));
deferred.resolve(true);
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
}
};
}]);
发出此请求时,我会收到以下信息:
XMLHttpRequest cannot load http://api.mydomain.io/login. Invalid HTTP status code 404
如果我将Laravel路线和AngularJS服务更改为使用GET,则一切都按预期工作。问题源于AngularJS .save()发出OPTIONS请求而不是POST(我不完全理解为什么)。
有没有人能帮助我找到合适的最佳实践解决方案?
谢谢!
答案 0 :(得分:7)
以下解决方案有效:
在filters.php中添加以下内容:
App::before(function($request)
{
if (Request::getMethod() == "OPTIONS") {
$headers = array(
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'X-Requested-With, content-type',);
return Response::make('', 200, $headers);
}
});
在routes.php的顶部添加以下内容:
header('Access-Control-Allow-Origin: http://app.mydomain.io');
感谢Google Plus社区! :)
莱昂。
答案 1 :(得分:0)
在客户端 http://docs.angularjs.org/api/ng。$ HTTP
您可以尝试设置默认的“设置HTTP标头”
答案 2 :(得分:0)
我已经用了很长时间来搞清楚这一点,这就是我想出来的:
Filters.php:
App::before(function($request)
{
header('Access-Control-Allow-Origin: http://app.mydomain.io');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization');
// Pre-flight request handling, this is used for AJAX
if($request->getRealMethod() == 'OPTIONS')
{
Log::debug('Pre flight request from Origin'.$rq_origin.' received.');
// This is basically just for debug purposes
return Response::json(array('Method' => $request->getRealMethod()), 200);
}
});
App.js(前端):
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
另请注意,Chrome和CORS请求中存在自签名SSL证书的错误,如果您对此感兴趣,我会提供链接。
所以建议在调试时使用Firefox(或者Chrome上的DevHTTPClient可以正常使用)。
干杯!
答案 3 :(得分:0)
试试新版本的Laravel(5 +)
public function handle($request, Closure $next)
{
$method = $request->method();
if($method == "OPTIONS"){
return response('It\'s supported. Relax!', 200);
}
return $next($request);
}