【问题标题】:How to remove Cache-control header no-cache如何删除缓存控制标头无缓存
【发布时间】:2018-06-07 15:43:13
【问题描述】:

我和我的团队正在开发一个 Laravel API,它与 Vue.js 前端进行通信,该前端使用 Apollo 客户端来使用 GraphQL 响应。

我们遇到了将缓存控制标头添加到响应中的问题。

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 配置中,我们找不到任何设置这些标头的内容。我检查了我们在 sites/available 中设置的全局 nginx.conf 和配置文件。

我可以将它添加到 nginx 配置中,但它只会添加另一个标题:

add_header Cache-Control "public";

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

如果此标头不是来自 PHP 或 nginx,那么它可能来自哪里? 我怎样才能删除或覆盖它?

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

【问题讨论】:

  • 尝试上传示例 HTML 并将其加载到浏览器中并检查其中是否存在缓存标头

标签: php laravel nginx graphql apollo


【解决方案1】:

在 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 在他的 comment 到 @the_hasanov's answer 中所述,可以通过实现中间件来覆盖标头。

  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,
  ];
...

【讨论】:

  • 经过数小时的搜索终于找到解决方案
【解决方案2】:

如果您使用的是 apache,您可以通过添加 .htaccess 来做到这一点

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

所以它将删除 Cache-Control:private 并将标题响应作为

Cache-Control:no-cache , public

【讨论】:

    【解决方案3】:

    在任何中间件中你都可以使用这个例子

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

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

    【讨论】:

    • 是的,使用 $response->header('Cache-Control','public') 它会更改 no-cache 标头。所以要么是 Laravel 添加这个头文件,要么是 laravel-graphql 包。
    猜你喜欢
    • 1970-01-01
    • 2011-01-13
    • 2017-01-10
    • 2011-02-05
    • 2020-09-24
    • 2019-01-14
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多