当尝试使用来自React应用程序的API(本地托管)登录时,每次都会出现此错误:
我知道这个领域有很多主题,但是没有一个对我有帮助。也许是因为我错过了一些东西,或者是不了解这个概念。
我不知道如何解决此问题。
我已经尝试过的事情
-添加了HTTP中间件(将跟随代码):无效。
-尝试使用spatie/laravel-cors
软件包进行修复:无效。
-尝试使用barryvdh/laravel-cors
进行修复:也不起作用。
我没主意了。有人知道我在做什么错吗?
我的代码
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
\Spatie\Cors\Cors::class, // <-- this line would be pointed to my own middleware when that would be in use
];
如果我要使用自己的中间件,则指向以下代码而不是\Spatie\Cors\Cors::class
class ApiCors
{
/**
* 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, PUT, DELETE, OPTIONS, PATCH')
->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
}
}
答案 0 :(得分:0)
实施CORS支持有些棘手的事情:
您的CORS中间件应添加到 global 中间件堆栈中,因为浏览器可以发送Preflight请求,并且您不希望每个API路由都有特定的OPTIONS
路由
中间件不需要将预检请求更深地传递给应用程序。
CORS标头应同时添加到Preflight请求和API请求中。
因此,应该这样做:
创建中间件:
php artisan make:middleware ApiCors
输入代码:
<?php
namespace App\Http\Middleware;
use Closure;
class ApiCors {
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
$isPreflight = $request->isMethod('options') && $request->hasHeader('origin');
// we don't need to process Preflight request further
$response = $isPreflight ? response()->make() : $next($request);
if($isPreflight) {
$response
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH')
->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization')
->header('Access-Control-Max-Age', 86400);
}
$response->header('Access-Control-Allow-Origin', $isPreflight ? '*' : ($request->header('origin') ?? '*'));
return $response;
}
}
注册中间件:
app/Http/Kernel.php
:
<?php
// ...
use App\Http\Middleware\ApiCors;
class Kernel extends HttpKernel {
// ...
protected $middleware = [
// ...
ApiCors::class,
];
// ...
protected $middlewarePriority = [
ApiCors::class, // move to the top of the chain
// ...
];
}
测试中间件:
让我们添加简单的API路由。
routes/api.php
:
Route::put('/v1/test', function () {
return response()->json(['answer' => 42]);
});
让我们启动简单服务器(在Laravel项目根文件夹中运行):
php -S localhost:8088 -t public
下一步,打开任何网页(或使用当前网页)并在开发者控制台中运行:
fetch('http://localhost:8088/api/v1/test', {
method: 'PUT', headers: { 'accept': 'application/json' }
}).then(r => r.json()).then(console.log.bind(console))
您应该得到答复:
{answer: 42}
请不要忘记将[外部] API路由添加到routes/api.php
,将 not 添加到routes/web.php
,因为Web路由器组有许多中间件,它们可能会干扰与您的api一起使用,例如VerifyCsrfToken
。