簡體   English   中英

如何刪除緩存控制 header 無緩存

[英]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,那么它可能來自哪里? 以及如何刪除或覆蓋它?

  • Laravel 5.5
  • Folkloreatelier/laravel-graphql
  • PHP 7.1
  • nginx 1.14.0
  • Ubuntu 16.04

在任何中間件中,您都可以使用此示例

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 的回答的評論中所述,可以通過實現中間件來覆蓋標頭。

  1. php artisan make:middleware CachePolicy

  2. 編輯新的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');
    }
}
  1. 修改app/http/Kernel.php以包含新的中間件:
...
protected $middleware = [
   ...
   \App\Http\Middleware\CachePolicy::class,
  ];
...

請注意, no cache並不意味着“不緩存”,它是no-storeno cache “允許緩存存儲響應但要求它們在重用之前重新驗證它。” 在此處查看https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control以獲取詳細信息。

要重新驗證,您的服務器響應應該有etagLast-Modified 在此處查看https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching以獲取詳細信息。 例如,在以“使用包含If-Modified-SinceIf-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

  1. 緩存控制

HTTP 允許緩存在與源服務器斷開連接時重用陳舊的響應。 must-revalidate 是防止這種情況發生的一種方法

  1. HTTP 緩存

過時的響應不會立即被丟棄。 HTTP 有一種機制可以通過詢問原始服務器將陳舊的響應轉換為新的響應...通過使用條件請求完成驗證

但我從來沒有想過no-cachemust-revalidate之間有多大區別,因為它們都需要驗證。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM