我在从 Angular 应用程序向 Slim PHP API 发出请求时遇到了与 CORS 相关的问题。我在控制台中收到以下错误消息:
来自客户端日志控制台的错误:XHROPTIONS http://localhost:8080/api/validate CORS 缺少允许凭据
Bloccata richiesta multiorigin(跨源):il criterio di 未经同意的原产地通讯 远程访问 http://localhost:8080/api/validate。 Motivo:预览“真实” 在 CORS 标头“Access-Control-Allow-Credentials”中。
Bloccata richiesta multiorigin(跨源):il criterio di 未经同意的原产地通讯 远程访问 http://localhost:8080/api/validate。动机:richesta CORS 非riuscita。状态抄本:(空)。 http://localhost:8080/api/validate 的 HTTP 失败响应:0 未知错误
这是我的中间件代码:
php
$fitnetApi->slim->add(function (Request $request, Response $response, callable $next) {
$uri = $request->getUri()->getPath();
// Controlla se l'URI inizia con '/api'
if (strpos($uri, '/api') === 0) {
$cookies = $request->getCookieParams();
$token = $cookies['jwt_token'] ?? null; // Usa l'operatore null coalescing
// Se non c'è un token, continua con il middleware successivo
if (!$token) {
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "token invalid"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
try {
// Decodifica il token
$decoded = JWT::decode($token, new Key('', 'HS256'));
// Controlla se il token è scaduto
if (isset($decoded->exp) && $decoded->exp < time()) {
$rtoken = $cookies['rjwt_token'] ?? null;;
$decRjwt = JWT::decode($rtoken, new Key('', 'HS256'));
// Controlla se il rtoken esiste e non è scaduto
if ($decRjwt && isset($decRjwt->exp) && $decRjwt->exp > time()) {
// Rigenera un token
$newToken = JWT::encode(
[
'id' => $decoded->id,
'type' => $decoded->type,
'exp' => time() + 60 * 15 // 15 minuti
],
"",
"HS256"
);
// Aggiunge il nuovo token come attributo alla richiesta
$request = $request->withAttribute('new_token', $newToken);
} else {
// Se il rtoken è scaduto, restituisci un errore
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "rtoken expired, renew auth"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
}
} catch (ExpiredException $e) {
// Gestisci il caso in cui il token JWT è scaduto
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "Token expired"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
} catch (SignatureInvalidException $e) {
// Gestisci il caso in cui il token JWT è invalido
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "Invalid token signature"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
} catch (\Exception $e) {
// Gestione generica di eccezioni JWT
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "Invalid token"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
}
// Continua con il prossimo middleware o la route
return $next($request, $response);
});
中间件中的cors设置:
$fitnetApi->slim->add(new Tuupola\Middleware\CorsMiddleware([
"origin" => ["http://localhost:8100"],
"methods" => ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
"headers.allow" => ["Token", "Authorization", "If-Match", "If-Unmodified-Since", "Content-Type"],
"headers.expose" => ["Authorization"],
"credentials" => true,
"cache" => 0,
]));
向 http://localhost:8080/api/validate 发出 POST 请求时出现错误。 尽管设置了 CORS 标头,我仍然收到状态为 0 的“未知错误”。
我已验证后端正在 localhost:8080 上运行。 API 正确响应通过 Postman 发出的请求。 我已经检查了 Angular 应用程序中的 JavaScript 错误。
可能导致这些 CORS 问题的原因是什么?如何修复错误以便我的 Angular 应用程序可以成功与 Slim PHP API 通信?
如有任何帮助,我们将不胜感激!
您需要通过单独添加处理程序来处理 Slim 中的 OPTIONS 请求
$app->options('/{routes:.+}', function ($request, $response, $args) {
return $response;
});