返回知识中心
网络

浏览器缓存与代理交互:安全复核路由变化

了解 HTTP 缓存、代理路由和缓存指令如何交互,让托管浏览器在路由变化时不会把缓存数据误认为实时响应。

文档中心

想直接进入 网络 文档吗?

这篇文章属于博客内容库。若你要步骤化配置、参考说明和持续更新,请直接进入对应 docs 分区。

浏览器缓存保存可复用的 HTTP 响应,让页面减少网络请求。代理会改变浏览器需要响应时使用的路径,但不会把缓存字节变成来自新路径的新响应。因此,评审应记录结果来自缓存、代理还是目标服务,并保持这些观察彼此分开。

关于代理配置,可阅读代理配置指南。浏览器存储机制对比介绍了 Cookie 和脚本存储,它们与 HTTP 缓存不同。

浏览器先检查缓存,再通过代理路由访问源站;图中将缓存新鲜度与路由责任分开表示。

浏览器缓存的作用

HTTP 缓存保存与请求对应的响应,以及决定能否复用的响应元数据。新鲜响应可以在不联系代理或源站的情况下满足后续请求。过期响应可能通过条件请求重新验证,而标记为 private 或其他不可共享的响应不能被共享缓存复用。RFC 9111定义了这些规则,MDN HTTP 缓存指南说明了浏览器行为。

缓存键不只是 URL。请求方法、选定的请求头、响应指令和缓存上下文都会影响是否匹配。响应头 Vary 可能要求按 Accept-Language 等请求头分别存储。缓存命中不能证明所有用户或所有路由都会收到相同字节。

缓存不是 Cookie、localStorage 或 IndexedDB。这些存储保存拥有独立范围和生命周期的应用状态。缓存响应可以包含公开或用户相关的表示数据,但它的复用由 HTTP 缓存元数据控制,而不是由脚本读取存储键控制。

代理路由改变什么

浏览器需要网络数据时会选择路径,并可能通过 HTTP、HTTPS 或 SOCKS 代理发送请求。代理会影响可达性、认证、DNS 处理和目标服务看到的地址。BotBrowser 可以为上下文配置获批代理,并让有文档支持的浏览器可见网络设置与该路由一致,但不能决定目标服务是否应提供内容或企业策略是否允许该路由。

缓存命中可能发生在使用路由之前。如果浏览器复用新鲜响应,改变代理不会让它重新获取。重新验证或缓存未命中会使用当前路由,因此路由变化可能影响验证请求、返回响应和新的缓存条目。比较运行结果时,同时记录缓存结果和路由标签。

代理不会自动看到每个缓存资源,目标服务响应也不能证明代理一定被联系。支持记录应区分“缓存命中”“通过路由 R 重新验证”“通过路由 R 获取”和“目标服务错误”。这些标签能让路由负责人和应用负责人根据正确证据行动。

路由变化与缓存响应

上下文打开时更换代理,会改变后续网络请求的路径,但不会清除 HTTP 缓存、Cookie 或其他存储,也不会改写已经渲染的响应。已经在途的请求可能在旧路由上完成,之后开始的请求可能使用新路由,因此过渡期间页面可能同时显示多个路由获取的内容。

把路由变化记录为新的网络片段,包括上下文标签、旧新路由标签、时间、缓存状态和可见结果。如果改变服务端状态的请求在切换期间超时,重试前先检查服务端状态;缓存 GET 与非幂等 POST 的重试安全性不同。

不要只为让新路由看起来可用而刷新或禁用缓存。先在记录明确的缓存状态下复现,再使用受控重新加载或应用提供的重新验证操作。清除站点数据可能同时删除 Cookie 和存储以及缓存条目,因此它改变的不只是网络路由,应作为独立测试条件记录。

共享缓存与私有缓存

当其他指令允许时,Cache-Control: public 允许共享缓存存储响应。private 告知共享缓存不要存储,但不代表浏览器缓存不能保留。no-store 要求缓存完全不存储,no-cache 允许存储但复用前必须验证。这些指令描述响应处理,并不是完整的授权模型。

个性化响应需要特别注意。按 Cookie、Authorization 或账户请求头变化的响应应设置合适标记和缓存键,不能被错误上下文获取。浏览器私有缓存属于配置文件或上下文,代理缓存则按配置和策略共享。不要因为浏览器使用私有上下文就推断代理也是私有的。

HTTPS 到目标站点的 TLS 会保护该连接,但不会使代理成为应用策略的可信负责人。企业检查、代理日志和保留规则是独立控制。调试记录中不要放凭证、账户数据或私有拓扑,检查响应头时使用获批的测试源站。

有界的故障排查流程

从已知响应和明确缓存状态开始。记录 URL、方法、相关缓存指令、上下文标签、路由标签和时间。先在计划研究的缓存条件下运行,再比较受控重新加载或重新验证。不要使用他人的账户或私有响应作为测试夹具。

在改变设置前分类结果:

  • **缓存命中:**资源不需要请求源站或代理。
  • **重新验证:**浏览器通过当前路由联系目标,由验证器决定存储响应是否仍可用。
  • **缓存未命中:**浏览器通过当前路由获取新响应。
  • **网络或目标服务失败:**请求到达路由或源站边界并返回有界失败。

如果路由变化后结果改变,先比较缓存状态。不同的目标响应可能来自不同路由、源站策略变化或缓存过期。不要把响应正文变化当作代理改写内容的证据,也不要把相同缓存字节当作新路由健康的证据。

只保留作出决定所需的证据:缓存相关响应头、路由标签、缓存状态、可见结果和负责人。遮盖 Cookie、Authorization 值、包含秘密的查询参数和私有响应正文。记录预期路由和缓存条件后,失败关闭本身就是有用结果。

检查顺序很重要,因为每一层都可能表现为成功。第一,记录浏览器是否尝试发出网络请求。开发者工具可能显示内存缓存或磁盘缓存,但这只是实现层观察,并非授权判断。Service worker 也可能从自己的缓存回答,因此页面成功并不表示联系了代理或源站。如果应用使用 service worker,应记录其版本和激活状态,并在说明中将其缓存与 HTTP 缓存分开。

第二,记录请求方法及操作是否会改变服务器状态。读取公开表示的 GET 通常比创建订单、发送消息或修改账户的 POST 更容易重放。HTTP 缓存规则不会让非幂等操作变得可安全重复。如果路由切换中断此类操作,应查询目标服务的处理状态,或使用应用请求标识,再决定是否重发。

第三,只采集能解释缓存决策的响应头。Age、Date、ETag、Last-Modified、Cache-Control、Expires、Vary 和 Warning 通常足以解释新鲜度和验证。不要为证明缓存结果而复制整个响应正文。精简的响应头记录也便于比较两个获批路由,且不会把用户内容放入工单。

第四,确认是否经过中间层。CDN、转发代理、企业网关或应用缓存都可能添加缓存状态头或改变时序,而浏览器自身的缓存结果没有改变。浏览器团队不应把中间层的保留策略归给配置文件负责人;网络团队也不应因为网关重新获取了副本,就声称浏览器缓存条目已失效。记录每项观察来自哪个边界。

第五,比较等价上下文。新上下文与长期使用的上下文可能因已有响应、service worker、Cookie 或验证器不同而得到不同结果。隐私浏览窗口可能采用不同保留规则,配置文件策略也可能禁用或分区存储。记录配置文件或上下文标签,但不要为了省事导出 Cookie 或私有响应数据。

第六,比较参与表示选择的请求头。Accept、Accept-Encoding、Accept-Language、授权状态、客户端提示和应用专用头都可能选择不同变体。Vary 说明这种选择,不代表必须按目标服务能观察到的每种属性变化。如果两个路由返回不同语言或压缩变体,应先核对请求头,再判断路由。

第七,区分缓存指令与清除操作。no-cache 不表示响应从未保存;验证成功仍可能返回 304 Not Modified,浏览器继续使用现有正文。no-store 限制响应存储,却不会追溯删除先前响应允许保存的副本。应用或管理员可能提供清除功能,应在变更记录中注明该功能的负责人和作用范围。

第八,把时间当作证据。两个请求之间响应可能变旧,部署后验证器可能变化,路由也可能有不同延迟或可用性窗口。使用一致时区记录时间戳,并将缓存年龄与当时生效的策略比较。如果响应来自本地缓存,不要用时钟差异证明路由已变更。

第九,在不扩大测试范围的前提下处理错误。304 是验证结果,200 可能是新鲜表示,404 可能是可缓存的否定响应,5xx 可能来自中间层或目标服务。状态码本身不能标识提供响应的层。将状态码与缓存状态、路由状态和可见应用结果一起记录。

第十,以负责人和下一步行动结束评审。如果浏览器复用了预期条目,结果就是缓存策略观察。如果当前路由从未被联系,网络负责人不能据此推断路由健康。如果响应已取回但被目标服务拒绝,应由账号或应用负责人决定后续。如果策略阻止获批测试,应停止并请策略负责人复核,不要改走未获批路由。这样可以维持可重复排查,同时保护私有内容,并区分缓存状态、路由行为和目标服务授权。

BotBrowser 的作用与边界

BotBrowser 可以提供可重复的浏览器配置文件和上下文,为每个上下文分配获批代理,并展示受控导航的浏览器可见结果。团队可据此比较文档化路由变化前后的缓存命中、重新验证和缓存未命中。如果测试有意包含 Cookie 状态,请参考 Cookie 管理文档。

BotBrowser 不管理企业或供应商缓存,不保证缓存驱逐时机,不检查私有响应内容,也不判断响应是否适合共享。路由变化不等于新配置文件;BotBrowser 也无法认证目标服务的缓存指令符合组织授权策略。缓存策略、代理保留和目标服务行为仍由各自负责人管理。

缓存键与表示边界

浏览器判断条目是否匹配时,会考虑地址栏之外的信息。请求方法、选定请求头、响应状态、新鲜度元数据、验证器和请求缓存模式都很重要。响应允许时,普通 GET 通常可缓存;比较测试不应默认 POST 可复用。按 Accept-Language 或 Accept-Encoding 变化的响应需要用 Vary 声明,以免一个表示被静默用于另一个请求。代理地址不会自动成为缓存键的一部分。

因此,同一 URL 可以有多个有效表示。公开应用外壳可能在所有区域相同,而 API 响应会按账户或地理位置选择。应测试预期会变化的资源,而不是清除页面上的所有资源。源站如果依据 Cookie 或授权头选择表示,也应发送指令,避免账户数据进入共享缓存。私有浏览器缓存可以为自己的配置文件保留此类响应,但这不代表它适合放进 CDN 或转发代理。

新鲜度与验证是不同观察。Cache-Control: max-age 和 Expires 说明条目在无需检查时可使用多久。过期条目仍可能有用:浏览器发送 If-None-Match 或 If-Modified-Since 并收到 304 Not Modified 后,旧正文仍保留,而验证元数据会更新。no-store 要求缓存不要保留响应;no-cache 允许存储,但复用前必须验证。记录实际指令,不要将所有旧结果都称为缓存故障。 浏览器缓存也不同于 Cache Storage、Cookie、localStorage 和 IndexedDB。后台处理器可以在 HTTP 缓存参与前从 Cache Storage 回答请求。于是登出后的页面看起来干净,账户相关响应却仍留在另一个存储中。只更换代理并清理一种存储,既没有改变路由边界,也没有清理完整会话状态。列出应用使用的存储并分别检查。

路由变化、在途请求与中间层

在打开的上下文中切换路由是交接,不是即时改写。在途请求可能仍通过旧路由完成;已加载文档的定时器也可能在切换期间继续发请求。等待待处理导航结束,暂停依赖旧路由的轮询,应用新路由并等待浏览器命令完成,然后发起新导航。不能仅因 URL 未变就把旧页面当作新路由的证据。

路由变化也会影响下一次未命中收到的响应。新响应可能带有不同的 ETag、Cache-Control、Vary 或 Age。如果这些值与表示不一致,浏览器就无法可靠地区分条目。该契约由源站负责。代理可以转发、缓存或添加策略头,但不能在响应保存后根据出口地址推断缺失的表示维度。

中间层带来另一个边界。浏览器未命中时,CDN 或转发代理可能返回共享条目,并附带 Age 或其他诊断头。相反,浏览器命中表示该资源没有发出请求,代理也就无从观察。记录应区分浏览器内存或磁盘命中、中间层命中、源站响应与失败。不要把一张页面截图当成所有字节来源的证明。

重定向响应可以独立于最终文档缓存。图片、脚本、字体和 API 调用也各自采用缓存决策。Service worker 只拦截其作用域内请求,且可应用与 HTTP 新鲜度无关的缓存策略。比较路由时检查请求序列,并确认承载区域或账户结果的资源来自哪一层。

共享与私有缓存归属

public、private、no-store 和 no-cache 描述存储处理,不会取代授权。标记 private 的响应可以留在某个配置文件的浏览器缓存中,但共享缓存不应保留它。符合规则的缓存不应写入 no-store 响应,不过 Cache Storage 的写入逻辑仍由应用负责。如果个性化数据必须离线可用,应明确 service worker 的策略。

每个获批测试目的都应有一个缓存所有者。账户上下文不应复用于另一个账户或区域,除非状态延续本身就是测试内容。新 BrowserContext 通常有独立的 Cookie、存储和缓存;在现有上下文切换代理会保留其存储状态。清理浏览器缓存不会清除 Cookie、service worker 缓存或账户会话;关闭上下文也应作为有证据记录的生命周期操作。

路由标签应说明用途,不暴露供应商秘密。维护一个简短登记,记下上下文标签、目标区域、路由负责人、被测缓存策略和交接时间。不要放代理凭据、客户标识、含秘密的完整 URL 或私有响应正文。供应商端点变化时更新路由分配并重新比较,不要拿新端点与旧观察记录对比。

进行受控区域测试时,可让组织自有端点返回安全的表示标识和区域标签。捕获该标识、相关缓存响应头、缓存模式、上下文,以及已知网络请求观察到的路由。发布标签或表示版本比时间戳更有用,因为它能表明源站是否改变了表示,而无需保留页面内容。证据要精简,并遮盖 Cookie、授权值和含秘密的查询参数。

安全失效与排障步骤

如果问题是旧状态是否造成影响,先创建全新上下文。为其设置目标路由,在组织控制的页面确认路由,然后请求测试资源。用相同方法、请求头和缓存模式与原上下文比较。若新上下文不同,原结果可能来自存储响应或 service worker 条目;若两者相同,再调查源站或中间层策略。

需要观察网络时,使用文档说明的验证式重新加载,或使用本次操作不读取存储条目的请求模式。将该观察与普通导航分开,因为强制网络请求改变了被测条件。不要一开始就大范围删除站点数据:这会删除 Cookie 和应用状态、改变账户行为,并掩盖原始缓存键问题。只失效拥有该表示的最窄一层。

按顺序检查:资源是浏览器内存或磁盘命中、service worker 响应、重新验证、未命中,还是目标服务失败;若发出了请求,它是否通过选定路由,中间层是否添加 Age 或其他缓存证据;源站是否声明语言、编码、授权或账户状态等全部表示维度;比较的上下文、配置文件、方法、URL、请求头和缓存模式是否等价;路由切换是否等在途请求结束后进行,切换后的检查是否使用新导航。

如果全新上下文检查后仍有意外结果,保留最小记录并请源站负责人复核策略。反复清理状态直到页面符合预期,不是有效验收标准。偏离预期的第一层应负责修正,例如补充缺失的 Vary 维度、隔离 service worker 缓存,或调整私有响应指令。

不要尝试缓存投毒、提取私有响应或检查他人的缓存。这些行为可能暴露数据,不属于授权排查流程。只使用组织控制的测试账户和端点。当缓存所有者、路由所有者或授权边界不清楚时应停止。

缓存键与表示边界(补充)

浏览器判断条目是否匹配时,会考虑请求方法、选定请求头、响应状态、新鲜度元数据、验证器和缓存模式。普通 GET 在响应允许时通常可缓存;比较测试不应默认 POST 可复用。按 Accept-Language 或 Accept-Encoding 变化的响应需要 Vary 声明,代理地址不会自动成为缓存键。同一 URL 可以有多个有效表示,例如所有区域相同的应用外壳和按账户或地理位置变化的 API 响应。测试预期变化的资源,而不是清除全部资源。源站按 Cookie 或授权头选择表示时,应避免账户数据进入共享缓存。max-age、Expires、no-store、no-cache 以及 304 Not Modified 分别表达新鲜度、存储和验证行为,应按实际响应记录。

浏览器缓存与 Cache Storage、Cookie、localStorage、IndexedDB 不同,service worker 可能在 HTTP 缓存之前回答。切换打开上下文的路由是交接,不是即时改写;在途请求可能仍走旧路由。等待导航结束,暂停旧路由轮询,等待新路由命令完成后再发起导航。CDN 或转发代理可能在浏览器未命中时命中;浏览器命中则代理根本看不到请求。重定向、图片、脚本、字体、API 和 service worker 也有独立缓存决策。

为每个授权测试目的指定缓存负责人。新 BrowserContext 通常有独立状态,切换现有上下文的代理会保留状态。登记上下文、区域、路由负责人、缓存策略和交接时间,不写入凭据、客户标识或私有正文。全新上下文配合受控端点可区分旧状态与源站行为;需要观察网络时使用文档化的重新验证模式,避免大范围清理掩盖缓存键问题。若仍有异常,保留最小证据交给源站负责人。不要缓存投毒、提取私有响应或检查他人缓存。

BotBrowser 可为每个上下文提供隔离会话和获批代理,帮助比较缓存命中、重新验证和未命中,并关联已知网络请求的路由。它不控制源站 Cache-Control、Vary、CDN、企业代理或后台处理器缓存,不能保证路由切换使任何缓存失效,也不判断响应是否可共享。参见代理配置文档。

公开来源

需要测试 Cookie 状态时,参阅 Cookie 管理文档。

#浏览器缓存#代理#HTTP 缓存#网络运维#隐私

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。