简体   繁体   English

如何删除缓存控制 header 无缓存

[英]How to remove Cache-control header no-cache

My team and I are working on a Laravel API which communicates with a Vue.js frontend that uses the Apollo client to consume the GraphQL responses.我和我的团队正在开发一个 Laravel API,它与使用 Apollo 客户端的 Vue.js 前端通信来使用 Z524DE6072ADEB36FB741 响应。

We have an issue with cache-control headers being added to the response.我们遇到了将缓存控制标头添加到响应中的问题。

Apollo cannot cache the contents because the response contains this header: Apollo 无法缓存内容,因为响应包含此 header:

Cache-Control: no-cache, private

In php.ini, we have this to disable sending cache-control headers by PHP:在 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 =

In the nginx config we cannot find anything that is setting those headers.在 nginx 配置中,我们找不到任何设置这些标头的内容。 I checked the global nginx.conf and config file we setup in sites/available.我检查了我们在站点/可用中设置的全局 nginx.conf 和配置文件。

I can add this to the nginx config, but it will only add another header:我可以将它添加到 nginx 配置中,但它只会添加另一个 header:

add_header Cache-Control "public";

Cache-Control: no-cache, private
Cache-Control: public

If this header is not coming from PHP or nginx, then where could it be coming from?如果这个 header 不是来自 PHP 或 nginx,那么它可能来自哪里? And how can I remove or overwrite it?以及如何删除或覆盖它?

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

in any middleware you can use this example在任何中间件中,您都可以使用此示例

public function handle($request, Closure $next)
{
    $response= $next($request);
    return $response->header('X-TEST-HEADER','test header value');
}

but i do not know this fix your problem但我不知道这能解决你的问题

you can do this by Adding in your .htaccess if you are using apache如果您使用的是 apache,您可以通过添加 .htaccess 来做到这一点

Header always set Cache-Control "no-cache, public"

so it will remove the Cache-Control:private and give the header response as所以它将删除 Cache-Control:private 并将标头响应作为

Cache-Control:no-cache , public

In Laravel, the Cache-Control: no-cache, private header is set in the vendor package Symfony http-foundation by the following logic:在 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;
    }

Source: Laravel 5.6 vendor/symfony/http-foundation/ResponseHeaderBag.php lines 269-299来源:Laravel 5.6 vendor/symfony/http-foundation/ResponseHeaderBag.php行 269-299

As the OP stated in his comment to @ the_hasanov's answer , the header can be overwritten by implementing a middleware.正如 OP 在他对@the_hasanov 的回答的评论中所述,可以通过实现中间件来覆盖标头。

  1. php artisan make:middleware CachePolicy

  2. edit the new app/Http/Middleware/Cachepolicy.php so that it reads:编辑新的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. Modify app/http/Kernel.php to include the new middleware:修改app/http/Kernel.php以包含新的中间件:
...
protected $middleware = [
   ...
   \App\Http\Middleware\CachePolicy::class,
  ];
...

Please note that no cache does NOT mean " don't cache ", which is no-store , no cache "allows caches to store a response but requires them to revalidate it before reuse."请注意, no cache并不意味着“不缓存”,它是no-storeno cache “允许缓存存储响应但要求它们在重用之前重新验证它。” Check here https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control for detailed information.在此处查看https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control以获取详细信息。

To revalidate, your server response should have etag or Last-Modified .要重新验证,您的服务器响应应该有etagLast-Modified Check here https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching for detailed information.在此处查看https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching以获取详细信息。 For example, at the section starts with "Validation is done by using a conditional request that includes an If-Modified-Since or If-None-Match request header."例如,在以“使用包含If-Modified-SinceIf-None-Match请求 header 的条件请求完成验证”部分开头。 So your server probably don't have those fields for revalidation.因此,您的服务器可能没有用于重新验证的这些字段。

The private means "cache that exists in the client. It is also called local cache or browser cache. It can store and reuse personalized content for a single user." private的意思是“存在于客户端的缓存。也称为本地缓存或浏览器缓存。它可以为单个用户存储和重复使用个性化的内容。”

@Vardkin's answer correctly pointed out it is in computeCacheControlValue() that set those fields, @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';
    }

I want to add that must-revalidate also explained in those articles I attached.我想补充一点,在我附加的那些文章中也解释了must-revalidate

  1. in Cache-Control缓存控制

HTTP allows caches to reuse stale responses when they are disconnected from the origin server. HTTP 允许缓存在与源服务器断开连接时重用陈旧的响应。 must-revalidate is a way to prevent this from happening must-revalidate 是防止这种情况发生的一种方法

  1. in HTTP cachingHTTP 缓存

Stale responses are not immediately discarded.过时的响应不会立即被丢弃。 HTTP has a mechanism to transform a stale response into a fresh one by asking the origin server...Validation is done by using a conditional request HTTP 有一种机制可以通过询问原始服务器将陈旧的响应转换为新的响应...通过使用条件请求完成验证

But I never figure how much difference between no-cache & must-revalidate since they all need to validate.但我从来没有想过no-cachemust-revalidate之间有多大区别,因为它们都需要验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM