可怕的CORS错误:
跨源请求已阻止:同源策略禁止在http://localhost/mysite/api/test上读取远程资源。 (原因:缺少CORS标题'Access-Control-Allow-Origin')。
Laravel路线:
$router->group(['prefix' => 'api', 'middleware' => 'cors'], function ($router) {
$router->get('/test', 'MyController@myMethod');
});
Laravel Cors中间件:
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, Authorization'
];
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;
}
Laravel内核:
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'cors' => \App\Http\Middleware\CORS::class
];
相关.htaccess:
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
相关的Vue.js:
new Vue({
el: '#app',
data: {
//data here
},
http: {
headers: {
"Authorization": "Basic " + "apiKeyHere"
}
},
methods: {
mymethod: function (e)
{
e.preventDefault();
this.$http.get('http://localhost/mysite/api/test').then(
function (response)
{
//do something
}
)
}
}
});
如果我取出Authorization标头选项,则请求有效。
我也尝试过https://github.com/barryvdh/laravel-cors,但仍然没有喜悦。任何帮助赞赏!
显然不是理想的解决方案,但它的工作原理。我已经将它添加到我的routes.php文件的顶部:
header('Access-Control-Allow-Origin: *');
header( 'Access-Control-Allow-Headers: Authorization, Content-Type' );
如果没有黑客攻击,这将是很好的...唉。
更新:原来是IIS相关。我最终在web.config文件中设置了标题,现在CORS可以在不破坏routes.php文件的情况下工作。
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Headers" value="Origin, Authorization, X-Requested-With, Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" />
</customHeaders>
</httpProtocol>
如果要限制访问,可以添加出站规则:
<outboundRules>
<clear />
<rule name="AddCrossDomainHeader">
<match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{HTTP_ORIGIN}" pattern="(http(s)?://((.+\.)?somesite\.com|(.+\.)?anothersite\.org))" />
</conditions>
<action type="Rewrite" value="{C:0}" />
</rule>
</outboundRules>
我解决了我的问题,只需在我的routes.php上添加这些行.Larara 5.2在routes / web.php中大于5.2
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, X-Auth-Token, Origin, Authorization');
或者在全局HTTP中间件堆栈中注册Cors中间件
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\CorsMiddleware::class
];
您的中间件还可以,但您需要在全局HTTP中间件堆栈中注册Cors中间件。
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\CorsMiddleware::class
];
事实上,这个问题来自于预检请求,但是当我们谈论Laravel时,处理方式需要一些额外的解释 - 主要是OPTIONS
请求被路由(其他答案是用PHP方式而不是Laravel方式),所以,你必须将它添加到你的路线才能成功:
Route::options('/{any}', function(){ return ''; })->where('any', '.*');
现在,让我们迎合所有其他方法 - 创建CORS中间件:
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', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE');
}
}
最后,对于给定的路由,使用该中间件:
Route::put('/test', function(){ echo('test'); })->with('cors');
你可以绕过这一个而不使用像Barryvdh \ Cors for Laravel这样的中间件,而这些中间件与JWT AUTH无法正常工作,我在内核实例化之前的Laravel中的index.php中添加了以下语句
header('Access-Control-Allow-Origin: http://localhost:8001');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token,Authorization');
header('Access-Control-Allow-Credentials: true');
之前添加这个
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
这应该适用于JWT AUTH。请注意,在Access-Control-Allow-Headers中,您应该包含Authorization,否则将不允许使用Authorization标头,因此JWT AUTH将失败。快乐的编码。
我的解决方案
$router->group(['prefix' => 'api', 'middleware' => 'cors'], function ($router){
$router->options('{param1?}/{param2?}/{param3?}', function () {});
});
这个答案是基于这个article。 barryvdh/laravel-cors中间件库,可用于解决问题(跨源资源共享)。
步骤1安装它:
composer require barryvdh/laravel-cors
步骤2发布库的供应商文件:
php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"
步骤3在步骤2中运行的命令将cors.php文件复制到config目录,如下所示:
return [
/*
|--------------------------------------------------------------------------
| Laravel CORS
|--------------------------------------------------------------------------
|
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supportsCredentials' => false,
'allowedOrigins' => ['*'],// ex: ['abc.com', 'api.abc.com']
'allowedHeaders' => ['*'],
'allowedMethods' => ['*'],// ex: ['GET', 'POST', 'PUT', 'DELETE']
'exposedHeaders' => [],
'maxAge' => 0,
];
对于allowedOrigins
,值可以是['*']
,表示请求的来源可以来自任何域,或者特定域的数组,这些域可以是我们允许向api
发送请求的起源,例如['first.com', 'second.com', 'register.third.com']
并且allowedMethods
可以是['*']
或允许的HTTP verbs
列表,例如['POST', 'GET']
步骤4注册cors中间件。打开app/Http/kernel.php
并将HandleCors
类添加到$routeMiddleware
,如下所示:
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'cors' => \Barryvdh\Cors\HandleCors::class, // add this line to enable cors to your routes
];
步骤5现在,您可以将laravel-cors
中间件添加到您想要的任何路径。例如在Routes/api.php
我会这样做:
Route::apiResource('category', 'CategoryController')->middleware('cors');
Route::apiResource('product', 'ProductController')->middleware('cors');