Я искал далеко и много для решения этой проблемы.
У меня есть веб-приложение AngularJS с базовым исполнением Laravel 4 следующим образом:
http://app.mydomain.io/ = AngularJS web app http://api.mydomain.io/ = Laravel Back-end
В файле routes.php в Laravel у меня есть следующий код 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 (я не совсем понимаю почему).
Может ли кто-нибудь помочь мне с правильным и лучшим решением?
Спасибо!
Было разработано следующее решение:
В пределах 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); } });
И наверху route.php добавьте следующее:
header('Access-Control-Allow-Origin: http://app.mydomain.io');
Благодаря сообществу Google Plus! 🙂
Леон.
На стороне клиента http://docs.angularjs.org/api/ng . $ Http
вы можете попробовать установить значение по умолчанию «Настройка заголовков HTTP»
Я использовал довольно некоторое время, выясняя это, и вот что я придумал:
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 (Frontend):
app.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.useXDomain = true; $httpProvider.defaults.withCredentials = true; delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
Также обратите внимание, что есть ошибка с самоподписанными сертификатами SSL в запросах Chrome и CORS, я предоставит ссылку, если вы этого заинтересованы.
Поэтому рекомендуется использовать Firefox при отладке (или DevHTTPClient на Chrome работает отлично для меня).
Ура!
Попробуйте этот кусок для более новых версий Laravel (5+)
public function handle($request, Closure $next) { $method = $request->method(); if($method == "OPTIONS"){ return response('It\'s supported. Relax!', 200); } return $next($request); }