如何使代理从源重新验证资源

2023-12-31

我的原始服务器在同一台机器上有一个 Nginx 反向代理。我希望代理缓存来自源的动态内容,但是当客户端重新验证资源时,我希望代理也使用源重新验证,而不仅仅是在不检查源的情况下向客户端返回 304。

例如,如果我将 max-age 设置为 60 秒,代理将很乐意在该时间段内返回 304,而无需检查源。我设置了一个测试,其中源每秒生成一个新的 etag,如下所示(使用 Node.js Express):

app.get('/dynamic/:file?', function(req, res){
  var filename = req.params.file;
  var filepath = path.join(__dirname, 'files', filename);
  res.setHeader('Cache-Control', 'public, must-revalidate, proxy-revalidate, max-age=60, s-maxage=60');
  res.setHeader('ETag', filename+etagCounter);
  res.sendfile(filepath);
  console.log('request', requestCounter++);
  console.log('etag', etagCounter);
  console.log('date', new Date().toISOString());
});

在 Nginx 中,传递此请求的路由配置如下:

location /cache/ {
  access_log on;

  add_header Vary "Accept-Encoding";

  add_header X-AppServer $upstream_addr;           # Backend Server / Port
  add_header X-AppServer-Status $upstream_status;  # Backend HTTP Status
  add_header X-Cache $upstream_cache_status;       # HIT / MISS / BYPASS / EXPIRED

  proxy_redirect      off;
  proxy_set_header    X-Real-IP            $remote_addr;
  proxy_set_header    X-Forwarded-For      $proxy_add_x_forwarded_for;
  proxy_set_header    X-Forwarded-Proto    $scheme;
  proxy_set_header    Host                 $http_host;
  proxy_set_header    X-NginX-Proxy        true;
  proxy_set_header    Connection           "";

  proxy_cache         one;
  proxy_cache_key     $scheme$proxy_host$uri$is_args$args;

  proxy_pass http://localhost:4444/;
}

当客户端直接与 Express 对话时,我看到 Express 返回 304,但是当中间存在代理时,Express 永远不会向 Nginx 返回 304。 Nginx 从缓存中提供服务,并且仅在 max-age 过去后才从源获取资源。

为了确保我将 etag 刷新间隔设置为 60 秒,将 max-age 设置为 1。因此,Nginx 每秒都会从源获取一个新资源(无需重新验证,因此会返回 200 响应),然后返回 304发送给客户端,直到 etag 在 60 秒后发生变化。

我的结论是 Nginx 永远不会与源服务器重新验证。只要它认为需要根据 max-age 获取资源的新副本,它就会获取一份新的资源副本。

有办法做我想做的事吗?它是否不尊重代理重新验证标头,或者我没有采取正确的方法?

[EDIT]

我已经找到答案了here http://odino.org/rest-better-http-cache/。根据这篇文章,我提出了 2 个解决方案。

1)缓存响应中的must-revalidate/proxy-revalidate应该足以让nginx在收到请求中的max-age=0时触发重新验证。

2) 当客户端在 CC 标头中发送“no-cache”时,代理肯定应该对源进行重新验证。

从我的测试来看,两者似乎都不起作用。例如我正在做这样的请求:

curl 'http://localhost:9088/cache/dynamic/image.jpg' -H 'If-None-Match: image.jpg0' -H 'Accept-Encoding: gzip,deflate,sdch' -H 'Host: localhost:9088' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Cache-Control: no-cache, max-age=0' -H 'Cookie: octane.sid=s%3AUa64F6fk2Pw0uwZ28e7OICyv.z2FNPYjQ7%2Fn%2F3vZGXV7B3QBYtqN%2FHzjV1e3XTuZcnmwduE4SBFEPDv3zE3zRuA4Ae705RtI6Z%2BBrqJyMveSjNA' -H 'Connection: keep-alive' -H 'If-Modified-Since: Thu, 06 Sep 2012 09:21:53 GMT' --compressed -I

它包含-H 'Cache-Control: no-cache, max-age=0',但我仍然从 nginx 缓存获取提供的内容,而无需检查来源。

Nginx 在这方面表现不佳吗?我使用的是1.5.4版本


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使代理从源重新验证资源 的相关文章

  • 如何在node.js中同步读取文件或Stream?

    请不要讲授关于我应该如何异步完成所有事情的讲座 有时我想以简单明显的方式做事 这样我就可以继续其他工作 由于某种原因 以下代码不起作用 它与我在 a 上找到的代码匹配最近的问题 https stackoverflow com questio
  • 控制台未打开时无法加载资源:net::ERR_EMPTY_RESPONSE

    我正进入 状态 Failed to load resource net ERR EMPTY RESPONSE 如果控制台未打开 我的 api 调用会出错 然而如果控制台打开 则 api 调用工作正常 前端使用 Angular2 后端使用 N
  • 如何读取节点中的单个位缓冲区

    如何读取节点中的单个位缓冲区 例如
  • nodejs knox 放入 s3 结果是 403

    我尝试在 nodejs 项目中使用 knox 上传到 Amazon s3 存储桶 但无法解决 403 错误 我已确保密钥 秘密和存储桶已正确设置 我真的需要那些有更多经验的人的帮助 我的节点代码如下 var upload test func
  • 通过插件管理器在 Notepad++ 中配置代理设置

    我想在 Notepad 中配置代理设置 以允许通过代理从互联网下载 在从网上搜索如何执行此操作后 我了解到我需要通过 设置 按钮在插件管理器中执行此操作 当我转到插件 gt 插件管理器 gt 显示插件管理器 gt 设置时 我看到下面的对话框
  • 调用 Mongoose 插件内模式的静态方法

    我写了一个插件 可以执行以下操作 module exports function schema options schema statics customFunction function criteria Code 这是我的架构 var
  • 用 Node.js 编写的 Azure Functions 可以访问连接字符串吗?

    Azure Function App 的应用程序设置包含可在门户中设置的数据库连接字符串的值 在 C 中 可以使用以下方式访问它们 ConfigurationManager ConnectionStrings ConnectionStrin
  • 让 Express 服务器接受 CORS 请求

    我的 Express 服务器运行在 http localhost 3000 我称之为网络服务器 我有另一个应用程序在 localhost 8100 上运行 我简称为 应用程序 当我的应用程序调用网络服务器时 我收到以下消息 XMLHTTPR
  • 自动执行异步函数

    下面的代码可以完美运行 const Course mongoose model Course courseSchema async function foo const nodeCourse new Course name Node JS
  • PHP-FPM 和 Nginx:502 错误网关

    配置 Ubuntu 服务器 11 10 64 位 亚马逊AWS Ec2 托管在云上 t1 micro实例 在我写任何其他内容之前 我想声明我已经检查了两者nginx 502 错误网关 https stackoverflow com ques
  • 启动nodejs时出错:openssl配置失败

    启动 Express 节点时出现以下错误 openssl 配置失败 错误 02001003 系统库 fopen 没有这样的 过程 节点无论如何都会启动 我没有尝试使用 SSL 这是起始代码 app Express app set port
  • 如何在 TypeScript 中获取源代码中的实际行号(用于自定义日志记录)

    参考文献这个问题 https stackoverflow com questions 1340872 how to get javascript caller function line number how to get javascri
  • 如何指定 Express 响应返回的类型

    我正在尝试使用 TypeScript 标准化我的express js Web应用程序中的响应 但我不太确定如何全局设置响应应该是这个接口 success boolean data any error string 现在我只是在写 async
  • Nodemailer:从未收到问候语

    当尝试使用 Nodemailer 在 Node 内发送电子邮件时 https github com nodemailer nodemailer https github com nodemailer nodemailer 调用sendMai
  • 使用 OpenSSL 在 PHP 中进行 AES 加密/在 Node.js 中进行解密

    我正在使用 PHP 和 Nodejs 使用 OpenSSL 进行对称加密 PHP 使用 OpenSSL 库 Node js 解密基于实现的加密 问题是 Node js 中的解密文本只是部分正确 PHP 加密函数 function encry
  • EJS在JS onload函数中访问express变量

    我知道你可以像这样获取 ejs 文件中变量的值 h1 h1 如果我要在同一个 ejs 页面的 onload javascript 函数中使用相同的标题变量 我将如何使用它 例如 这个函数产生一个控制台错误说 未捕获的语法错误 意外的标识符
  • 使用 IP 地址连接到另一台计算机

    我在计算机上安装了 NodeJS 并运行了一些测试 一切正常my机器 现在我想要一个不在同一网络中的朋友连接到我的计算机 以便 NodeJS 可以响应我朋友的请求 但我不知道 我必须在哪个IP和端口上监听 我也不知道 我必须给我的朋友哪个I
  • 在 GraphQL 服务器中实现访问控制的好模式是什么?

    背景 我有一组模型 包括用户和各种其他模型 其中一些模型包含对用户的引用 我公开这些模型 以便通过 GraphQL API 生成的查询Graffiti https github com RisingStack graffiti 由 Mong
  • 如何删除控制台中打印的字符

    我一直在搜索如何用其他语言执行此操作 发现必须使用特殊字符 b 来删除最后一个字符 如何删除控制台应用程序中打印的字符 linux https stackoverflow com questions 430713 how do i eras
  • Node / Express Handlebars - 在哪里定义自定义助手

    我正在开发一个节点 快速 车把应用程序 我刚刚发现了自定义助手 但我不知道在哪里定义它们 我尝试在实际视图模板 hbs 文件中添加一些

随机推荐

  • 使用 JavaScript 在特定延迟后执行脚本

    有没有类似 jQuery 的 JavaScript 方法delay or wait 将脚本的执行延迟特定的时间 只是为了补充其他人所说的内容setTimeout 如果以后想调用带参数的函数 就需要设置一些匿名函数调用 您需要将该函数作为参数
  • Golang 的 Codeclimate 测试覆盖率格式化程序

    无处可去Codeclimate 文档 https docs codeclimate com v1 0 docs setting up test coverage section supported languages and formats
  • 控制模板可见性触发器

    我对下面的按钮样式所做的只是让按钮仅在 IsMouseOver 或 IsPressed 时可见 它的编写方式甚至无法编译 找不到 Glyph 如何清理这个问题 直到 IsMoueOver 时按钮可见 Cheers Berryl
  • 我应该等待 ValueTask 吗?

    这将是一个有效的实施ValueTask请 缓存服务从缓存或数据库返回数据 public async ValueTask
  • 如何在 PowerShell 中检查现有文件后关闭表单 GUI?

    我想检查一个现有的文件 如果进程仍在等待该文件 它将显示一个GUI窗口 文件存在后 窗口将自动关闭 我尝试了这段代码 窗口无法关闭 即使文件已经存在 检查文件 SN 708TSTA MAC 2E5961370 function Find n
  • R根据条件返回列名

    对于以下数据框 DF lt data frame Row c 1 2 3 4 5 2 04 c 1 1 0 1 1 2 05 c 0 0 0 0 1 2 06 c 1 0 0 0 1 2 07 c 1 0 0 0 1 2 08 c 1 1
  • 具有多个父项的 Activity 的 Android 向上导航

    我在实施时遇到问题向上导航在具有此导航树的应用程序上 后退按钮的标准实现很好 当尝试实现向上按钮时 问题就开始了 我的期望 当用户开机时详情 5 活动然后按向上按钮 应用程序将转到清单 3 活动 当用户开机时详情 7 活动然后按向上按钮应用
  • SQLite - 替换字符串的一部分

    是否可以使用SQL in an SQLite表替换部分字符串 例如 我有一个表 其中一个字段保存文件的路径 是否可以替换字符串的某些部分 例如 c afolder afilename bmp becomes c anewfolder afi
  • Ruby Torrent 库

    Ruby 有什么好的库可以与 BitTorrent 跟踪器一起使用吗 下载或种子文件 rubyforge 上有一个 ruby torrent 库 但它最后一次更新是在 2005 年 似乎不再工作了 参见 lib torrent ruby h
  • 了解 C# 字段初始化要求

    考虑以下代码 public class Progressor private IProgress
  • 如何使用 PHP DOM 查询从 HTML 表中选择文本?

    如何使用 PHP DOM 查询从 HTML 表格单元格获取文本 HTML 表格是 table tr th Job Location th td a href Kabul a td tr tr th Nationality th td Afg
  • C# 中的索引错误,其中数组应返回空数组但返回超出范围

    我是 C 新手 遇到错误 需要让 DataPoints 数组返回空 但无论出于何种原因 我都会收到此错误 我在这里做错了什么 指数超出范围 必须为非负数且小于 集合 r n参数名称 索引 var DataPoints new DataPoi
  • 错误错误:StaticInjectorError(AppModule)[UserformService -> HttpClient]:

    在尝试添加 PrimeNG 表时 我在这里破坏了我的构建 https github com BillyCharter87 Tech O Dex UI tree BrokeIt https github com BillyCharter87
  • ISO UTC DateTime 格式作为 MVC 6 API 响应中的默认 json 输出格式

    有谁知道如何在返回 DateTime 对象时将 MVC6 的 json 输出配置为默认为 ISO UTC DateTime 字符串格式 在 WebApi2 中 我可以设置 JsonFormatter SerializerSettings 并
  • 如何为strip文件配置cmake

    当我在发布模式下使用 cmake 时 我有以下二进制文件 64 bit LSB executable x86 64 version 1 SYSV dynamically linked interpreter lib64 ld linux x
  • 通过 Link Server 连接时,如何将 Oracle TIMESTAMP 数据类型转换为 SQL Server DATETIME2 数据类型。

    我已经尝试过一些例子 但到目前为止还没有工作 我有一个Link Server SQL Server 2014 to an Oracle 12C Database 该表包含数据类型 TIMESTAMP 其数据如下 22 MAR 15 04 1
  • 胖模型/瘦控制器与服务层[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我多年来一直使用 Net 开发企业应用程序 我的应用程序通常有一个域模型 其中包含映射到 SQL DB 表的实体 我使用存储库模式 依赖注入和服
  • 梯度下降与随机梯度下降算法

    我尝试在 MNIST 手写数字数据集 包括 60K 训练样本 上训练前馈神经网络 我每次都迭代所有训练样本 表演反向传播对于每个时期的每个这样的样本 运行时间当然太长了 我运行的算法是否命名为梯度下降 我读到对于大型数据集 使用随机梯度下降
  • Google Apps 脚本 - createEvent 函数不创建日历事件

    我们正在尝试使用 Google 表单创建在线表单来接受预约请求 这个过程应该是这样的 用户填写表格并提交信息 有效 一封电子邮件会发送到我们的 Gmail 通知我们有新的传入请求 这有效 我们进入谷歌电子表格 有3张 一张名为Request
  • 如何使代理从源重新验证资源

    我的原始服务器在同一台机器上有一个 Nginx 反向代理 我希望代理缓存来自源的动态内容 但是当客户端重新验证资源时 我希望代理也使用源重新验证 而不仅仅是在不检查源的情况下向客户端返回 304 例如 如果我将 max age 设置为 60