This commit is contained in:
ct
2025-07-15 05:56:55 +08:00
parent 758db107d2
commit 3efc976dab
5 changed files with 155 additions and 6 deletions

View File

@@ -0,0 +1,57 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Spatie\ResponseCache\Hasher\RequestHasher;
class InertiaResponseCacheHasher implements RequestHasher
{
public function getHashFor(Request $request): string
{
$hashParts = [
$request->getMethod(),
$request->getPathInfo(),
$request->getQueryString(),
];
// Include Inertia-specific headers in the hash
if ($request->header('X-Inertia')) {
$hashParts[] = 'inertia';
// Include the Inertia version if present
if ($version = $request->header('X-Inertia-Version')) {
$hashParts[] = "version:{$version}";
}
// Include partial reload components if present
if ($partial = $request->header('X-Inertia-Partial-Component')) {
$hashParts[] = "partial:{$partial}";
}
if ($data = $request->header('X-Inertia-Partial-Data')) {
$hashParts[] = "data:{$data}";
}
} else {
$hashParts[] = 'html';
}
// Include user agent for mobile/desktop differences if needed
// $hashParts[] = $this->getUserAgentHash($request);
return md5(implode('|', array_filter($hashParts)));
}
/**
* Get a simplified hash of user agent for mobile/desktop caching
*/
protected function getUserAgentHash(Request $request): string
{
$userAgent = $request->userAgent() ?? '';
// Simple mobile detection
$isMobile = preg_match('/Mobile|Android|iPhone|iPad/', $userAgent);
return $isMobile ? 'mobile' : 'desktop';
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Spatie\ResponseCache\CacheProfiles\CacheProfile;
use Symfony\Component\HttpFoundation\Response;
class InertiaResponseCacheProfile implements CacheProfile
{
public function shouldCacheRequest(Request $request): bool
{
// Only cache GET requests
if (! $request->isMethod('GET')) {
return false;
}
// Don't cache requests with query parameters (except for tracking parameters)
$allowedQueryParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'ref'];
$queryParams = array_keys($request->query());
$disallowedParams = array_diff($queryParams, $allowedQueryParams);
if (! empty($disallowedParams)) {
return false;
}
// Don't cache authenticated requests
if ($request->user()) {
return false;
}
// Don't cache admin routes
if ($request->is('admin*') || $request->is('horizon*')) {
return false;
}
// Cache both regular page loads and Inertia AJAX requests
return true;
}
public function shouldCacheResponse(Response $response): bool
{
// Only cache successful responses
if (! $response->isSuccessful()) {
return false;
}
// Cache both HTML responses (initial page loads) and JSON responses (Inertia navigation)
$contentType = $response->headers->get('content-type', '');
return str_contains($contentType, 'text/html') ||
str_contains($contentType, 'application/json');
}
public function cacheNameSuffix(Request $request): string
{
// Different cache keys for HTML vs JSON responses
if ($request->header('X-Inertia')) {
return '_inertia_json';
}
return '_html';
}
public function isRunningInConsole(): bool
{
return app()->runningInConsole();
}
public function enabled(Request $request): bool
{
return config('responsecache.enabled', true);
}
public function cacheRequestUntil(Request $request): \DateTime
{
$cacheTime = config('responsecache.cache_lifetime_in_seconds', 60 * 60 * 24 * 7);
return now()->addSeconds($cacheTime)->toDateTime();
}
public function useCacheNameSuffix(Request $request): string
{
return $this->cacheNameSuffix($request);
}
}