![](/img/trans.png)
[英]Laravel response Cache-Control headers always containing 'no-cache'
[英]How to remove Cache-control header no-cache
我和我的團隊正在開發一個 Laravel API,它與使用 Apollo 客戶端的 Vue.js 前端通信來使用 Z524DE6072ADEB36FB741 響應。
我們遇到了將緩存控制標頭添加到響應中的問題。
Apollo 無法緩存內容,因為響應包含此 header:
Cache-Control: no-cache, private
在 php.ini 中,我們有這個來禁用 PHP 發送緩存控制頭:
; Set to {nocache,private,public,} to determine HTTP caching aspects
; or leave this empty to avoid sending anti-caching headers.
; http://php.net/session.cache-limiter
session.cache_limiter =
在 nginx 配置中,我們找不到任何設置這些標頭的內容。 我檢查了我們在站點/可用中設置的全局 nginx.conf 和配置文件。
我可以將它添加到 nginx 配置中,但它只會添加另一個 header:
add_header Cache-Control "public";
Cache-Control: no-cache, private
Cache-Control: public
如果這個 header 不是來自 PHP 或 nginx,那么它可能來自哪里? 以及如何刪除或覆蓋它?
在任何中間件中,您都可以使用此示例
public function handle($request, Closure $next)
{
$response= $next($request);
return $response->header('X-TEST-HEADER','test header value');
}
但我不知道這能解決你的問題
如果您使用的是 apache,您可以通過添加 .htaccess 來做到這一點
Header always set Cache-Control "no-cache, public"
所以它將刪除 Cache-Control:private 並將標頭響應作為
Cache-Control:no-cache , public
在 Laravel 中, Cache-Control: no-cache, private
標頭通過以下邏輯在供應商包 Symfony http-foundation 中設置:
/**
* Returns the calculated value of the cache-control header.
*
* This considers several other headers and calculates or modifies the
* cache-control header to a sensible, conservative value.
*
* @return string
*/
protected function computeCacheControlValue()
{
if (!$this->cacheControl) {
if ($this->has('Last-Modified') || $this->has('Expires')) {
return 'private, must-revalidate'; // allows for heuristic expiration (RFC 7234 Section 4.2.2) in the case of "Last-Modified"
}
// conservative by default
return 'no-cache, private';
}
$header = $this->getCacheControlHeader();
if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
return $header;
}
// public if s-maxage is defined, private otherwise
if (!isset($this->cacheControl['s-maxage'])) {
return $header.', private';
}
return $header;
}
來源:Laravel 5.6 vendor/symfony/http-foundation/ResponseHeaderBag.php
行 269-299
正如 OP 在他對@the_hasanov 的回答的評論中所述,可以通過實現中間件來覆蓋標頭。
php artisan make:middleware CachePolicy
編輯新的app/Http/Middleware/Cachepolicy.php
使其顯示:
<?php
namespace App\Http\Middleware;
use Closure;
class CachePolicy
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// return $next($request);
$response= $next($request);
return $response->header('Cache-Control','no-cache, public');
}
}
app/http/Kernel.php
以包含新的中間件:...
protected $middleware = [
...
\App\Http\Middleware\CachePolicy::class,
];
...
請注意, no cache
並不意味着“不緩存”,它是no-store
, no cache
“允許緩存存儲響應但要求它們在重用之前重新驗證它。” 在此處查看https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control以獲取詳細信息。
要重新驗證,您的服務器響應應該有etag
或Last-Modified
。 在此處查看https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching以獲取詳細信息。 例如,在以“使用包含If-Modified-Since
或If-None-Match
請求 header 的條件請求完成驗證”部分開頭。 因此,您的服務器可能沒有用於重新驗證的這些字段。
private
的意思是“存在於客戶端的緩存。也稱為本地緩存或瀏覽器緩存。它可以為單個用戶存儲和重復使用個性化的內容。”
@Vardkin 的回答正確地指出是在設置這些字段的computeCacheControlValue()中,
if (!$this->cacheControl) {
if ($this->has('Last-Modified') || $this->has('Expires')) {
return 'private, must-revalidate'; // allows for heuristic expiration (RFC 7234 Section 4.2.2) in the case of "Last-Modified"
}
// conservative by default
return 'no-cache, private';
}
我想補充一點,在我附加的那些文章中也解釋了must-revalidate
。
HTTP 允許緩存在與源服務器斷開連接時重用陳舊的響應。 must-revalidate 是防止這種情況發生的一種方法
過時的響應不會立即被丟棄。 HTTP 有一種機制可以通過詢問原始服務器將陳舊的響應轉換為新的響應...通過使用條件請求完成驗證
但我從來沒有想過no-cache
和must-revalidate
之間有多大區別,因為它們都需要驗證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.