我一直试图解决这个问题一段时间,但无法破解它。
我有一个Laravel后端和角形前端。这些是在不同的领域,因为前端需要是一个网络和移动cordova应用程序。
即使添加了CORS中间件,邮件和资源请求也无法加载,我得到了
No 'Access-Control-Allow-Origin' header is present on the requested resource
控制台中出现错误。
以下获取请求可以正常工作: -
Route::get('example', ['middleware' => 'cors', function(){
return Response::json(array('name' => 'Steve Jobs 1', 'company' => 'Apple'));
}]);
但是下面的那些失败了 -
Route::group(['middleware' => 'cors'], function () {
Route::group(['prefix' => 'api'], function()
{
Route::resources('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController@authenticate');
});
});
我关注https://scotch.io/tutorials/token-based-authentication-for-angularjs-and-laravel-apps。
我的CORS.php
class CORS
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
header("Access-Control-Allow-Origin: *");
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
];
if($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
return $next($request);
}
}
kernel.php
class Kernel extends HttpKernel
{
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
/*\App\Http\Middleware\VerifyCsrfToken::class,*/
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
'cors' => 'App\Http\Middleware\CORS',
];
}
答案 0 :(得分:0)
答案 1 :(得分:0)
也许您可以使用以下内容暂时解决它:
我在我的控制器构造中添加了cors中间件,如下所示:
public function __construct()
{
// Apply the jwt.auth middleware to all methods in this controller
// except for the index method.
$this->middleware('jwt.auth', ['except' => ['index']]);
$this->middleware('cors');
}
在我的内核中:
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
'cors'=> \Barryvdh\Cors\HandleCors::class
];
这似乎对我有用。另外,检查laravel日志并调试控制器。我的控制器中有一个拼写错误,我客户端控制台中的http响应是cors错误。
答案 2 :(得分:0)
现在几个小时都有同样的问题。尝试了不同的解决方案(使用barryvdh/laravel-cors library,制作了我自己的CORS中间件,在index.php文件中添加了标题)但没有任何帮助我。
现在我使用https://github.com/neomerx/cors-illuminate并且它有效。
cors-illuminate库和laravel-cors库之间的区别之一在安装指南中。 在cors-illuminate指南中,它明确表示您必须在
之后直接添加中间件行\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
如果您在CheckForMaintenanceMode中间件之后直接添加中间件,也许laravel-cors库也可以工作。没试过。
答案 3 :(得分:0)
在我的情况下,错误是我正在执行在使用jwt进行autenticate之前包含请求的调用。 我有这个导致问题的代码:
vertex.attributes(g)
$name
[1] "2943" "822" "922" "1694" "1739" "2891" "1096" "267" "767" "839"
[11] "1348" "350" "523" "3641" "1587" "3671" "2666" "2956" "699" "755"
V(g)[1]
+ 1/20 vertex, named:
[1] 2943
V(g)[V(g)$name == 2943]
+ 1/20 vertex, named:
[1] 2943
如您所见,JWTAuth行在使用$ request的行之前。 您可以将JWTAuth行移动到函数中的forst行,也可以在类中创建一个构造函数,如下所示:
function store(Request $request)
{
$producto = new Producto($request->json()->all());
$this->currentUser = JWTAuth::parseToken()->authenticate();
$producto->cliente_id = $this->currentUser->cliente_id;
$producto->save();
return json_encode($producto);
}
这解决了cors问题。 我用Barryvdh Cors。
答案 4 :(得分:0)
我正面临着类似的事情。在公共目录中编辑.htaccess文件后,它运行良好。以下是htaccess文件:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Authorization"
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
让我知道此解决方案是否适合您
确保通过运行在htaccess中启用标头
sudo a2enmod headers
答案 5 :(得分:0)
Cors处理程序是使用此软件包https://github.com/fruitcake/laravel-cors
的最新Laravel版本中的内置功能。答案 6 :(得分:0)
因此,当我在 api.php 中使用自己的 CORS 中间件而不使用水果蛋糕 (barryvdh/laravel-cors) 时,我遇到了同样的问题,并花了数小时进行调试并找出问题所在。
经过数小时的调试和挫折,我发现当您在组中使用中间件时,它不会立即得到应用。
当您发送请求时,laravel 会读取 api.php 并“注册”所有路由和中间件并“记住”它们,而无需实际执行它们。在它“注册”所有这些(读取整个 api.php
文件)之后,它执行一个函数,在该函数中它输入来自 URL 的路径和请求中使用的 HTTP 方法,然后它开始查找路由匹配 URL 和 HTTP 方法,找到一个后,它执行该路由所在的中间件,然后执行控制器方法。
例如,对于您的代码,当您向 GET
发送 /api/authenticate
请求时,它匹配资源方法 index
,然后执行中间件 cors
,因此它可以工作并从您的控制器返回数据。
当您向 POST
发送 PUT
、DELETE
、PATCH
或 /api/authenticate
请求时,浏览器首先发送 OPTIONS
请求,所以 laravel 会“注册”所有路由,然后使用 URL 和 HTTP 方法执行“匹配”(现在是 OPTIONS
)。
但是没有具有 OPTIONS
方法的路由,resources
也没有 OPTIONS
方法,因此由于没有具有 {{1} 方法的路由} 方法,laravel 不匹配任何内容,因此它不会执行那些您最终处理 OPTIONS
方法的中间件。
OPTIONS
示例
api.php
“匹配”函数称为 Route::group(['middleware' => 'cors'], function () {
Route::group(['prefix' => 'api'], function() {
Route::resources('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController@authenticate');
});
});
,它位于 findRoute
。
vendor/laravel/framework/src/Illuminate/Routing/Router.php
当您使用 /**
* Find the route matching a given request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Routing\Route
*/
protected function findRoute($request)
{
$this->current = $route = $this->routes->match($request);
$this->container->instance(Route::class, $route);
return $route;
}
记录 $route
,然后发出 error_log(json_encode($route), 0);
请求,然后查看错误日志时,您可以看到成功的“匹配”并且它应用了 {{1 }} 控制器:
GET
但是当您发送 cors
请求时,会发生这种情况:
{"uri":"api\/authenticate","methods":["GET","HEAD"],"action":{"middleware":["cors"],"uses":"App\\Http\\Controllers\\AuthenticateController@index","controller":"App\\Http\\Controllers\\AuthenticateController@index","namespace":null,"prefix":"api","where":[]},"isFallback":false,"controller":null,"defaults":[],"wheres":[],"parameters":[],"parameterNames":[],"computedMiddleware":null,"compiled":{}}
在那里你可以看到实际上发送了 PUT
方法(因为浏览器首先发送了一个 {"uri":"api\/authenticate","methods":["OPTIONS"],"action":{"uses":{}},"isFallback":false,"controller":null,"defaults":[],"wheres":[],"parameters":[],"parameterNames":[],"computedMiddleware":null,"compiled":{}}
方法)并且没有匹配到并且没有应用中间件,因此 OPTIONS
请求失败了CORS 错误 (OPTIONS
)
PUT
数组中的中间件被应用之后 Laravel 成功地将路由与路径和 HTTP 方法匹配,因为不同的路由可以有不同的中间件。Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
数组中的中间件(全局中间件)在 Laravel 开始注册和匹配路由之前应用。要解决此问题,您必须在 $routeMiddleware
数组中使用全局中间件来处理 $middleware
方法。您可以只使用处理它的 Fruitcake 一个,然后您可以在 $middleware
中使用您自己的 CORS 中间件,该中间件可以根据您的喜好设置不同的标头(例如,不同路由/组/前缀的不同 Allowed Origins .
答案 7 :(得分:0)
对于 cors,我建议使用这个包。 https://github.com/fruitcake/laravel-cors
但是,如果您有大量请求。最好在 nginx 或 apache 级别配置 cors。会有nginx比php-fpm可以处理大量的请求,所以会优化性能。