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

sun*_*mad 3 php nginx laravel apollo graphql

我和我的团队正在研究 Laravel API,它与 Vue.js 前端通信,前端使用 Apollo 客户端来使用 GraphQL 响应。

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

Apollo 无法缓存内容,因为响应包含以下标头:

Cache-Control: no-cache, private
Run Code Online (Sandbox Code Playgroud)

在 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 =
Run Code Online (Sandbox Code Playgroud)

在 nginx 配置中,我们找不到任何设置这些标头的内容。我检查了我们在站点/可用中设置的全局 nginx.conf 和配置文件。

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

add_header Cache-Control "public";

Cache-Control: no-cache, private
Cache-Control: public
Run Code Online (Sandbox Code Playgroud)

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

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

小智 5

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

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

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

  • 是的,使用 $response->header('Cache-Control','public') 它会更改无缓存标头。所以要么是 Laravel 添加了这个标头,要么是 laravel-graphql 包。 (2认同)

Var*_*kin 5

在 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;
    }
Run Code Online (Sandbox Code Playgroud)

来源:Laravel 5.6vendor/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');
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 修改app/http/Kernel.php以包含新的中间件:
...
protected $middleware = [
   ...
   \App\Http\Middleware\CachePolicy::class,
  ];
...
Run Code Online (Sandbox Code Playgroud)