laravel 如何删除缓存控制标头no-cache

iqjalb3h  于 2023-02-17  发布在  其他
关注(0)|答案(5)|浏览(211)

我和我的团队正在开发一个Laravel API,该API与使用Apollo客户端来使用GraphQL响应的Vue.js前端通信。
我们遇到了一个将缓存控制标头添加到响应中的问题。
Apollo无法缓存内容,因为响应包含此标头:

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和我们在sites/available中设置的配置文件。
我可以将此添加到nginx配置中,但它只会添加另一个标头:

add_header Cache-Control "public";

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

如果这个头文件不是来自PHP或nginx,那么它会来自哪里呢?我该如何删除或覆盖它?

  • 拉腊维尔5.5
  • 民间文学家/拉腊维尔-图形
  • PHP 7.1语言
  • nginx1.14.0
  • Ubuntu 16.04
dpiehjr4

dpiehjr41#

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

public function handle($request, Closure $next)
    {
        $response = $next($request);
        return $response instanceof \Symfony\Component\HttpFoundation\Response
            ? $response->header('pragma', 'no-cache')
                ->header('Cache-Control', 'no-store,no-cache, must-revalidate, post-check=0, pre-check=0')
                ->header('X-ANY-HEADER', 'any header value')
            : $response;
    }

但是我不知道这能解决你的问题

5sxhfpxr

5sxhfpxr2#

在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 x 1 m1n1x第269-299行 *

正如OP在他对@the_hasanov的回答的评论中所说的那样,可以通过实现中间件来覆盖头部。

  1. php artisan make:middleware CachePolicy
    1.编辑新的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,
  ];
...
bkhjykvo

bkhjykvo3#

如果你正在使用apache,你可以通过在你的.htaccess中添加来完成

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

因此它将删除Cache-Control:private并给予如下报头响应

Cache-Control:no-cache , public
nszi6y05

nszi6y054#

请注意,no cache并不意味着“不要缓存",no-storeno cache“允许缓存存储响应,但要求它们在重用之前重新验证它。”
要重新验证,您的服务器响应应该包含etagLast-Modified。请在此处查看https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching以获取详细信息。例如,在以“Validation is done by using aconditional requestthat include a If-Modified-Since or If-None-Match request 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.在Cache-Control
HTTP允许缓存在与源服务器断开连接时重新使用过时响应。must-revalidate是防止这种情况发生的一种方法
1.在HTTP缓存中
过时的响应不会立即被丢弃。HTTP有一种机制,可以通过请求源服务器将过时的响应转换为新的响应...验证是通过使用条件请求完成的
但是我从来没有计算过no-cachemust-revalidate之间有多大的区别,因为它们都需要验证。
Which one to use : Expire Header, Last Modified Header or ETags的一个答案是“ETagLast-Modified stamp之间的差异更具有语义性",这可能会给予一些线索,但如果no-cachemust-revalidate都需要验证差异是什么?

92vpleto

92vpleto5#

在.htaccess文件中添加以下代码

Header always set Cache-Control "no-cache, no-store, must-revalidate"

您可以设置任何您想要的策略,但重要的一点是要记住有“标题总是设置"。

相关问题