Laravel 5 + AngularJS 跨域 CORS
Laravel 5 + AngularJS Cross Domain CORS
我到处寻找答案,但到目前为止没有任何效果。堆栈上列出的所有解决方案都没有被证明是足够的。
我的 laravel 日志中没有任何错误形式,我只得到标准:
XMLHttpRequest cannot load http://api.domain.dev/post/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://domain.dev' is therefore not allowed access.
Laravel 控制器:
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Post;
use App\Tag;
use Illuminate\Http\Request;
class PostController extends Controller {
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$posts = Post::with('user', 'tags')->get();
return response()->json($posts);
}
}
Laravel 路线:
<?php
Route::resource('user', 'UserController');
Route::resource('post', 'PostController');
Route::get('post/tag/{tag}', 'PostController@postsWithTag');
Route::resource('tag', 'TagController');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
有点臃肿没有条理angular:
//App
var app = angular.module('app', [
'ngRoute',
'ngAnimate'
]);
//Config
app.config(['$routeProvider', '$locationProvider', '$animateProvider', function($routeProvider, $locationProvider, $animateProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider.
when('/', {
templateUrl: 'partials/home.html',
controller: 'PageController'
}).
when('/about', {
templateUrl: 'partials/about.html',
controller: 'AboutController'
}).
when('/contact', {
templateUrl: 'partials/contact.html',
controller: 'ContactController'
}).
when('/blog', {
templateUrl: 'partials/blog.html',
controller: 'PostsController'
}).
when('/blog/post/:postId', {
templateUrl: 'partials/post.html',
controller: 'PostController'
}).
otherwise({
redirectTo: '/'
});
}]);
//Factory
app.factory('Data', function Data($http) {
return {
getPosts: function getPosts() { return $http.get('http://api.domain.dev/post/'); },
getPost: function getPost(id) { return $http.get('http://api.domain.dev/post/' + id); },
addPost: function addPost(data) { return $http.post('http://api.domain.dev/post/', data); },
removePost: function removePost(id) { return $http.delete('http://api.domain.dev/post/'+ id); },
getTags: function getTags() { return $http.get('http://api.domain.dev/tag/'); },
getTag: function getTag(id) { return $http.get('http://api.domain.dev/tag/' + id); },
addTag: function addTag(data) { return $http.post('http://api.domain.dev/tag/', data); },
removeTag: function removeTag(id) { return $http.delete('http://api.domain.dev/tag/'+ id); },
}
});
//Posts Controller
app.controller('PostsController', function PostsController($scope, Data) {
Data.getPosts().success(parsePosts);
function parsePosts(data) {
$scope.posts = data;
}
//AddPost
$scope.newPost = { title: '', content: '', resume: '' };
$scope.addPost = function addPost(){Data.addPost({ title: $scope.newPost.title, content: $scope.newPost.content, resume: $scope.newPost.resume, user_id: $scope.newPost.user_id }).success(postAddSuccess).error(postAddError);}
function postAddSuccess(data) {
$scope.error = null;
$scope.posts.push(data);
$scope.newPost = { title: '', content: '', resume: '' };
}
function postAddError(data) {
$scope.error = data;
}
//RemovePost
$scope.removePost = function removePost(id) {
if (confirm('Do you really want to remove this post?')) {
Data.removePost(id).success(postRemoveSuccess);
}
}
function postRemoveSuccess(data) {
var i = $scope.posts.length;
while (i--) {
if ($scope.posts[i].id == data) {
$scope.post.splice(i, 1);
}
}
}
});
//Post Controller
app.controller('PostController', function PostController($scope, $routeParams, Data) {
Data.getPost($routeParams.id).success(parsePost);
function parsePost(data) {
$scope.post = data;
}
Data.getTags($routeParams.id).success(parsePostsTags);
function parsePostsTags(data) {
$scope.tags = data;
}
$scope.newTag = { tag: '' };
$scope.addTag = function addTag() {
$scope.newTag.post_id = $scope.post.id;
Data.addTag($scope.newTag).success(tagAddSuccess).error(tagAddError);
}
function tagAddSuccess(data) {
$scope.error = null;
$scope.tags.push(data);
$scope.newTag = { tag: '' };
}
function tagAddError(data) {
$scope.error = data;
}
$scope.removeTag = function removeTag(id) {
if (confirm('Do you really want to remove this tag?')) {
Data.removeTag(id).success(tagRemoveSuccess);
}
}
function tagRemoveSuccess(data) {
var i = $scope.tags.length;
while (i--) {
if ($scope.tags[i].id == data) {
$scope.tags.splice(i, 1);
}
}
}
});
//About Controller
app.controller('AboutController', function AboutController($scope, Data) {
});
//Portfolio Controller
app.controller('PortfolioController', function PortfolioController($scope, Data) {
});
//Contact Controller
app.controller('ContactController', function ContactController($scope, Data) {
});
//Page Controller
app.controller('PageController', function PageController($scope, Data) {
});
我不知道从这里去哪里。
我已经尝试了从正常的 header()
实现到使用 laravel-cors 包通过过滤器和控制器中的 _construct 实现的所有方法。
我也走了服务器配置路线并尝试将 header 添加到 .htaccess 和虚拟主机配置中。
在return之前添加这一行header("Access-Control-Allow-Origin: *");
您的代码应该是
public function index()
{
$posts = Post::with('user', 'tags')->get();
header("Access-Control-Allow-Origin: *");
return response()->json($posts);
}
我不太了解 laravel.but 我的建议是请求 headers 访问 REST 方法(GET,POST,PUT,DELTE)和特定来源您通过以下方式从哪个域发出请求的域,或者设置为“*”(它允许任何域)
header('Access-Control-Allow-Origin', 'some url');
header('Allow', 'GET, POST, OPTIONS');
header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Request-With');
header('Access-Control-Allow-Credentials', 'true');
在 angular js.If 您使用 <1.2 您可以在控制器文件中设置 CORS,如下所示 way.In 不需要最新版本它将设置 default.you 需要设置什么您期望从服务器默认获得的内容类型是 json.If 您期望您可以在请求中手动设置的其他类型的内容。
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
当您调用跨源 XHR 请求时,javascript 首先向给定的 URL 触发 OPTIONS 请求。如果此方法未添加到您的路由中,则它会弹出一个 404 页面,该页面在没有 ACAO header 的情况下提供,因此不会发送具体的 POST 请求,因为 javascript 看到它不允许.
添加
<?php header("Access-Control-Allow-Origin: *"); ?>
到public/index.php如果它在蓝铃之类的函数中不起作用建议
将这些行添加到您的 public/index.php:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token'); // allow certain headers
看看,是否有效。
我遇到了同样的问题,但是 jQuery 我花了几个星期才找到一个好的解决方案。
我的情况是创建一个中间件来设置 headers 是完美的解决方案。
创建Cors中间件:App\Http\Middleware\Cors.php
namespace App\Http\Middleware;
use Closure;
class Cors
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', $_SERVER['HTTP_ORIGIN'])
// Depending of your application you can't use '*'
// Some security CORS concerns
//->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'POST, OPTIONS')
->header('Access-Control-Allow-Credentials', 'true')
->header('Access-Control-Max-Age', '10000')
->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
}
}
记得在里面设置Cors别名App\Http\Kernel
protected $routeMiddleware = [
...
'cors' => \App\Http\Middleware\Cors::class,
];
在路由内部,您可以将中间件与组一起使用或直接指向特定路由,例如:
Route::match(['post', 'options'], 'api/...', 'Api\XController@method')->middleware('cors');
如果有人在使用jQuery时遇到这个问题,我建议使用$.ajax,而不是$.get、$.post。使用此方法时,jQuery 使用 XMLHttpRequest 发送数据并将 content-type 设置为 application/x-www-form-urlencoded,无法更改,因此请使用 Ajax.
例如:
$.ajax({
type: 'POST',
url: 'www.foo.bar/api',
contentType: "application/json",
xhrFields: {
// The 'xhrFields' property sets additional fields on the XMLHttpRequest.
// This can be used to set the 'withCredentials' property.
// Set the value to 'true' if you'd like to pass cookies to the server.
// If this is enabled, your server must respond with the header
// 'Access-Control-Allow-Credentials: true'.
withCredentials: true
},
headers: {
// Set any custom headers here.
// If you set any non-simple headers, your server must include these
// headers in the 'Access-Control-Allow-Headers' response header.
'Accept': 'application/json'
},
data: '{"some":"json data"}',
success: function (data) {
console.log('AJAX version');
console.log("Works!")
},
});
记住:如果您根据要求使用 application/json header,您必须提供 "OPTIONS" 方法来进行预检。
关于 CORS 的更多信息:http://www.html5rocks.com/en/tutorials/cors/
我做了什么,但不确定这是否是最好的解决方案,但那个没有任何问题
1.build angular 通常使用 ng build --prod
2.move angular/dist
到 laravel/public
的内容
3.then 在 laravel/routes/web.php
中使用这个简单的代码
Route::prefix('api')->group(function () {
Route::get('/', function () {
return view('welcome');
});
});
Route::get('/{params?}', function () {
// return view('welcome');
include_once '../public/index.html';
})->where('params', '(.*)');
现在所有请求都到达 Laravel,如果它可以通过路由捕获请求,则该路由将起作用,否则它将传递给 angular
我到处寻找答案,但到目前为止没有任何效果。堆栈上列出的所有解决方案都没有被证明是足够的。
我的 laravel 日志中没有任何错误形式,我只得到标准:
XMLHttpRequest cannot load http://api.domain.dev/post/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://domain.dev' is therefore not allowed access.
Laravel 控制器:
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Post;
use App\Tag;
use Illuminate\Http\Request;
class PostController extends Controller {
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$posts = Post::with('user', 'tags')->get();
return response()->json($posts);
}
}
Laravel 路线:
<?php
Route::resource('user', 'UserController');
Route::resource('post', 'PostController');
Route::get('post/tag/{tag}', 'PostController@postsWithTag');
Route::resource('tag', 'TagController');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
有点臃肿没有条理angular:
//App
var app = angular.module('app', [
'ngRoute',
'ngAnimate'
]);
//Config
app.config(['$routeProvider', '$locationProvider', '$animateProvider', function($routeProvider, $locationProvider, $animateProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider.
when('/', {
templateUrl: 'partials/home.html',
controller: 'PageController'
}).
when('/about', {
templateUrl: 'partials/about.html',
controller: 'AboutController'
}).
when('/contact', {
templateUrl: 'partials/contact.html',
controller: 'ContactController'
}).
when('/blog', {
templateUrl: 'partials/blog.html',
controller: 'PostsController'
}).
when('/blog/post/:postId', {
templateUrl: 'partials/post.html',
controller: 'PostController'
}).
otherwise({
redirectTo: '/'
});
}]);
//Factory
app.factory('Data', function Data($http) {
return {
getPosts: function getPosts() { return $http.get('http://api.domain.dev/post/'); },
getPost: function getPost(id) { return $http.get('http://api.domain.dev/post/' + id); },
addPost: function addPost(data) { return $http.post('http://api.domain.dev/post/', data); },
removePost: function removePost(id) { return $http.delete('http://api.domain.dev/post/'+ id); },
getTags: function getTags() { return $http.get('http://api.domain.dev/tag/'); },
getTag: function getTag(id) { return $http.get('http://api.domain.dev/tag/' + id); },
addTag: function addTag(data) { return $http.post('http://api.domain.dev/tag/', data); },
removeTag: function removeTag(id) { return $http.delete('http://api.domain.dev/tag/'+ id); },
}
});
//Posts Controller
app.controller('PostsController', function PostsController($scope, Data) {
Data.getPosts().success(parsePosts);
function parsePosts(data) {
$scope.posts = data;
}
//AddPost
$scope.newPost = { title: '', content: '', resume: '' };
$scope.addPost = function addPost(){Data.addPost({ title: $scope.newPost.title, content: $scope.newPost.content, resume: $scope.newPost.resume, user_id: $scope.newPost.user_id }).success(postAddSuccess).error(postAddError);}
function postAddSuccess(data) {
$scope.error = null;
$scope.posts.push(data);
$scope.newPost = { title: '', content: '', resume: '' };
}
function postAddError(data) {
$scope.error = data;
}
//RemovePost
$scope.removePost = function removePost(id) {
if (confirm('Do you really want to remove this post?')) {
Data.removePost(id).success(postRemoveSuccess);
}
}
function postRemoveSuccess(data) {
var i = $scope.posts.length;
while (i--) {
if ($scope.posts[i].id == data) {
$scope.post.splice(i, 1);
}
}
}
});
//Post Controller
app.controller('PostController', function PostController($scope, $routeParams, Data) {
Data.getPost($routeParams.id).success(parsePost);
function parsePost(data) {
$scope.post = data;
}
Data.getTags($routeParams.id).success(parsePostsTags);
function parsePostsTags(data) {
$scope.tags = data;
}
$scope.newTag = { tag: '' };
$scope.addTag = function addTag() {
$scope.newTag.post_id = $scope.post.id;
Data.addTag($scope.newTag).success(tagAddSuccess).error(tagAddError);
}
function tagAddSuccess(data) {
$scope.error = null;
$scope.tags.push(data);
$scope.newTag = { tag: '' };
}
function tagAddError(data) {
$scope.error = data;
}
$scope.removeTag = function removeTag(id) {
if (confirm('Do you really want to remove this tag?')) {
Data.removeTag(id).success(tagRemoveSuccess);
}
}
function tagRemoveSuccess(data) {
var i = $scope.tags.length;
while (i--) {
if ($scope.tags[i].id == data) {
$scope.tags.splice(i, 1);
}
}
}
});
//About Controller
app.controller('AboutController', function AboutController($scope, Data) {
});
//Portfolio Controller
app.controller('PortfolioController', function PortfolioController($scope, Data) {
});
//Contact Controller
app.controller('ContactController', function ContactController($scope, Data) {
});
//Page Controller
app.controller('PageController', function PageController($scope, Data) {
});
我不知道从这里去哪里。
我已经尝试了从正常的 header()
实现到使用 laravel-cors 包通过过滤器和控制器中的 _construct 实现的所有方法。
我也走了服务器配置路线并尝试将 header 添加到 .htaccess 和虚拟主机配置中。
在return之前添加这一行header("Access-Control-Allow-Origin: *");
您的代码应该是
public function index()
{
$posts = Post::with('user', 'tags')->get();
header("Access-Control-Allow-Origin: *");
return response()->json($posts);
}
我不太了解 laravel.but 我的建议是请求 headers 访问 REST 方法(GET,POST,PUT,DELTE)和特定来源您通过以下方式从哪个域发出请求的域,或者设置为“*”(它允许任何域)
header('Access-Control-Allow-Origin', 'some url');
header('Allow', 'GET, POST, OPTIONS');
header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Request-With');
header('Access-Control-Allow-Credentials', 'true');
在 angular js.If 您使用 <1.2 您可以在控制器文件中设置 CORS,如下所示 way.In 不需要最新版本它将设置 default.you 需要设置什么您期望从服务器默认获得的内容类型是 json.If 您期望您可以在请求中手动设置的其他类型的内容。
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
当您调用跨源 XHR 请求时,javascript 首先向给定的 URL 触发 OPTIONS 请求。如果此方法未添加到您的路由中,则它会弹出一个 404 页面,该页面在没有 ACAO header 的情况下提供,因此不会发送具体的 POST 请求,因为 javascript 看到它不允许.
添加
<?php header("Access-Control-Allow-Origin: *"); ?>
到public/index.php如果它在蓝铃之类的函数中不起作用建议
将这些行添加到您的 public/index.php:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token'); // allow certain headers
看看,是否有效。
我遇到了同样的问题,但是 jQuery 我花了几个星期才找到一个好的解决方案。
我的情况是创建一个中间件来设置 headers 是完美的解决方案。
创建Cors中间件:App\Http\Middleware\Cors.php
namespace App\Http\Middleware;
use Closure;
class Cors
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', $_SERVER['HTTP_ORIGIN'])
// Depending of your application you can't use '*'
// Some security CORS concerns
//->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'POST, OPTIONS')
->header('Access-Control-Allow-Credentials', 'true')
->header('Access-Control-Max-Age', '10000')
->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
}
}
记得在里面设置Cors别名App\Http\Kernel
protected $routeMiddleware = [
...
'cors' => \App\Http\Middleware\Cors::class,
];
在路由内部,您可以将中间件与组一起使用或直接指向特定路由,例如:
Route::match(['post', 'options'], 'api/...', 'Api\XController@method')->middleware('cors');
如果有人在使用jQuery时遇到这个问题,我建议使用$.ajax,而不是$.get、$.post。使用此方法时,jQuery 使用 XMLHttpRequest 发送数据并将 content-type 设置为 application/x-www-form-urlencoded,无法更改,因此请使用 Ajax.
例如:
$.ajax({
type: 'POST',
url: 'www.foo.bar/api',
contentType: "application/json",
xhrFields: {
// The 'xhrFields' property sets additional fields on the XMLHttpRequest.
// This can be used to set the 'withCredentials' property.
// Set the value to 'true' if you'd like to pass cookies to the server.
// If this is enabled, your server must respond with the header
// 'Access-Control-Allow-Credentials: true'.
withCredentials: true
},
headers: {
// Set any custom headers here.
// If you set any non-simple headers, your server must include these
// headers in the 'Access-Control-Allow-Headers' response header.
'Accept': 'application/json'
},
data: '{"some":"json data"}',
success: function (data) {
console.log('AJAX version');
console.log("Works!")
},
});
记住:如果您根据要求使用 application/json header,您必须提供 "OPTIONS" 方法来进行预检。
关于 CORS 的更多信息:http://www.html5rocks.com/en/tutorials/cors/
我做了什么,但不确定这是否是最好的解决方案,但那个没有任何问题
1.build angular 通常使用 ng build --prod
2.move angular/dist
到 laravel/public
3.then 在 laravel/routes/web.php
Route::prefix('api')->group(function () {
Route::get('/', function () {
return view('welcome');
});
});
Route::get('/{params?}', function () {
// return view('welcome');
include_once '../public/index.html';
})->where('params', '(.*)');
现在所有请求都到达 Laravel,如果它可以通过路由捕获请求,则该路由将起作用,否则它将传递给 angular