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,那么它可能来自哪里?我该如何删除或覆盖它?
小智 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)
但我不知道这能解决你的问题
在 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的回答的评论中所述,可以通过实现中间件来覆盖标头。
php artisan make:middleware CachePolicy
编辑新内容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)
app/http/Kernel.php以包含新的中间件:...
protected $middleware = [
...
\App\Http\Middleware\CachePolicy::class,
];
...
Run Code Online (Sandbox Code Playgroud)