Yazılar · Laravel · Inertia · Önbellek
Laravel ve Inertia sitesi geri tuşunda ham JSON gösteriyor: Hostinger edge'i ve Vary başlığı
Inertia aynı adres için biri HTML biri JSON iki cevap üretir ve bunları Vary: X-Inertia ile ayırır. Hostinger'ın edge katmanı bu başlığı koşulsuz Accept-Encoding ile ezer; tarayıcı iki cevabı tek önbellek kaydı sanır ve geri tuşunda JSON'ı basar. Vary'yi düzeltmeye çalışma, edge yine ezer. X-Inertia başlıklı isteklere Cache-Control: no-store ver; no-cache yetmez, çünkü Chrome geri tuşunda yeniden doğrulamayı atlayabilir.
Bir müşteri sitesinin otomotiv sayfasında zaman zaman şu görünüyordu: {"component":"Vehicles/Index","props":{…}}. Sayfa değil, ham JSON; Chrome'un "okunaklı hale getir" kutucuğuyla. Rastgele, tekrar tekrar, hep aynı kişide. Sunucu tarafında her şey doğruydu ve tam da bu yüzden teşhis uzadı. Bu yazı kısa: nasıl doğrulanır, neden olur, nasıl kapanır.
Önce sunucuyu akla
curl ile normal bir istek at. Content-Type: text/html ve düzgün HTML dönüyorsa sunucuda hata yok. Kesin kanıt JSON'ın içindeki version hash'i: canlı sitenin şu anki sürümüyle karşılaştır, farklıysa kullanıcının gördüğü şey eski bir deploy'dan kalma tarayıcı önbelleğidir, sunucudan hiç gelmemiştir.
curl -s https://SITE/YOL | grep -oE '"version":"[a-f0-9]+' | head -1
Kök neden
Inertia'da aynı adres iki farklı cevap döner: normal gezinmede HTML, uygulama içi gezinmede, yani X-Inertia: true başlığıyla, JSON. Inertia bunları ayırmak için cevaba Vary: X-Inertia koyar. Hostinger'ın edge katmanı ise Vary'yi koşulsuz Accept-Encoding ile eziyor; sıkıştırmayı kapatınca da aynı, yani her cevapta oluyor. Sonuç: tarayıcı iki cevabı tek önbellek kaydı sanıyor ve geri ya da ileri tuşunda elindeki JSON'ı ekrana basıyor.
Cache-Control: no-cache bunu kurtarmıyor. no-cache, "sakla ama kullanmadan doğrula" demektir ve Chrome geçmiş gezinmesinde yeniden doğrulamayı atlayabiliyor. Kaydın hiç oluşmaması gerekiyor.
Çözüm: no-store, Vary'ye güvenme
Inertia isteklerinin cevabını hiç saklatma. Inertia middleware'inden sonra çalışan bir güvenlik başlığı middleware'inde:
if ($request->headers->has("X-Inertia")) {
$response->headers->set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
$response->headers->set("Pragma", "no-cache");
}
// edge bir gün ezmeyi bırakırsa doğru ayrım kendiliğinden devreye girsin
$response->headers->set("Vary", "X-Inertia, Accept-Encoding");
Middleware sırası önemli: bootstrap/app.php içindeki web(append: [...]) listesinde bu sınıf HandleInertiaRequests'ten önce yazılmalı; dıştaki middleware'in cevap aşaması sonra çalışır ve Inertia'nın başlığının üstüne yazabilir. HTML cevabına dokunma: yalnız X-Inertia başlıklı istekler no-store olur, normal sayfalar no-cache, private kalır; oturum güvenliği ve olağan önbellek davranışı bozulmaz. Yalnız PHP dosyası değişiyor, derleme gerekmiyor.
Doğrulama
V=$(curl -s https://SITE/YOL | grep -oE '"version":"[a-f0-9]+' | head -1 | sed 's/.*"//')
curl -sS -D - -o /dev/null https://SITE/YOL -H "X-Inertia: true" -H "X-Inertia-Version: $V" \
| grep -iE "^(Content-Type|Cache-Control)" # application/json + no-store
curl -sS -D - -o /dev/null https://SITE/YOL -H "Accept: text/html" \
| grep -iE "^(Content-Type|Cache-Control)" # text/html + no-cache, private
Tarayıcıda: uygulama içi bağlantıyla sayfaya git, geri, ileri; document.contentType hâlâ text/html olmalı. X-Inertia gönderip sürüm göndermezsen 409 ve X-Inertia-Location dönmesi hata değil, Inertia'nın varlık sürümü protokolü; doğru sürümü de gönder.
Zehirlenmiş önbellek kendiliğinden temizlenmez
Düzeltmeden sonra o adresin bozuk kaydını taşıyan tarayıcılar bir kez daha JSON görebilir. Kullanıcıya sert yenileme söyle, sonrası temiz. Düzeltmeyi "artık olmuyor" diye değil, yukarıdaki curl çıktısıyla kapat.
Bu yazı neye dayanıyor
8 Ağustos 2026, Laravel 12 ve Inertia 2 üzerinde çalışan bir kurumsal site. Belirti rastgeleydi, sunucu masumdu, kanıt sürüm hash'iydi. Aynı gün kapandı ve o günden beri tekrarlamadı.
Yazılım ve sistem mimarı, AlgowAI'da COO. Bu yazıdaki her şey canlı bir sistemde ölçülerek yaşandı; tahmin yok. Sorun sende de varsa yaz, bakarım.