ChatGPT解决这个技术问题 Extra ChatGPT

浏览器缓存 HTTP 301 多长时间?

我正在调试 HTTP 301 永久重定向的问题。经过快速测试,Safari似乎在重新启动时清除了301s的缓存,但Firefox没有。

IE、Chrome、Firefox 和 Safari 什么时候清除它们的 301 缓存?

例如,如果我想将 1.example 重定向到 2.example,但我不小心将其设置为重定向到 3.example,那就有问题了。我可以纠正这个错误,但在此期间访问过 1.example 的任何人都会缓存到 3.example 的错误重定向,因此在清除缓存之前他们将无法访问 1.example2.example .经过调查,我发现没有设置 Cache-ControlExpires 标头。不正确的 301 响应的标头应该是这样的:

HTTP/1.1 301 Moved Permanently
Date: Wed, 27 Feb 2013 12:05:53 GMT
Server: Apache/2.2.21 (Unix) DAV/2 PHP/5.3.8
X-Powered-By: PHP/5.3.8
Location: http://3.example/
Content-Type: text/html

我自己的测试表明:

IE7、IE8、Android 2.3.4 根本不缓存。

Firefox 18.0.2、Safari 5.1.7(在 Windows 7 上)和 Opera 12.14 所有缓存,并在浏览器重新启动时清除缓存。

IE10 和 Chrome 25 缓存,但在浏览器重启时不清除,那么它们什么时候会清除呢?

请告诉 chrome 我们需要一条摆脱这个 301 地狱洞的方法:bugs.chromium.org/p/chromium/issues/…
@BT 因为这个问题会影响所有浏览器,所以实际上只有 IETF 可以解决这个问题,可能是通过在没有 TTL 的缓存 301 上定义一些强制超时,以便浏览器最终重新验证他们缓存的假设。
我开始在 IETF 邮件列表上讨论这个问题,如果有人仍然关注这个问题,感觉想参与进来:lists.w3.org/Archives/Public/ietf-http-wg/2017OctDec/0363.html

t
thomasrutter

在没有另外指定的缓存控制指令的情况下,301 重定向默认为被缓存而没有任何到期日期。

也就是说,只要浏览器的缓存可以容纳它,它就会一直缓存。如果您手动清除缓存,或者清除缓存条目为新条目腾出空间,它将从缓存中删除。

您至少可以在 Firefox 中通过转到 about:cache 并在磁盘缓存下找到它来验证这一点。它在其他浏览器(包括 Chrome 和基于 Chromium 的 Edge)中以这种方式工作,尽管它们没有用于检查缓存的 about:cache

在所有浏览器中,仍然可以使用缓存指令覆盖此默认行为,如下所述:

如果您不希望缓存重定向

这种无限期缓存只是这些浏览器在没有其他指定标头的情况下的默认缓存。逻辑是您指定“永久”重定向并且没有给他们任何其他缓存指令,因此他们会将其视为您希望无限期缓存它。

如果指定了任何其他响应,浏览器仍会像任何其他响应一样遵守 Cache-Control 和 Expires 标头。

您可以将 Cache-Control: max-age=3600Expires: Thu, 01 Dec 2014 16:00:00 GMT 等标头添加到 301 重定向。您甚至可以添加 Cache-Control: no-cache 使其不会被浏览器永久缓存,或者添加 Cache-Control: no-store 使其甚至不能被浏览器存储在临时存储中。

但是,如果您不希望重定向是永久性的,那么使用 302 或 307 重定向可能是更好的选择。发出 301 重定向但将其标记为不可缓存是违背 301 重定向的精神的,即使它在技术上是有效的。 YMMV,您可能会发现“永久”重定向具有时间限制的边缘情况。请注意,浏览器默认不会缓存 302 和 307 重定向。

如果您之前发出了 301 重定向但想取消该操作

如果人们在他们的浏览器中仍然有缓存的 301 重定向,那么无论源页面是否仍然有重定向,他们都会继续被带到目标页面。您解决此问题的选项包括:

一个简单的解决方案是再次发出另一个重定向。如果浏览器在重定向期间第二次被重定向回同一个 URL,它应该再次从源获取它,而不是再次从缓存中重定向,以避免重定向循环。对此答案的评论表明这现在适用于所有主要浏览器 - 但可能有一些次要浏览器不支持。

如果您无法控制上一个重定向目标所在的站点,那么您就不走运了。尝试请求网站所有者重定向回您。

预防胜于治疗 - 如果您不确定是否要永久停用旧 URL,请避免 301 重定向。


此外,您是否有任何参考资料表明浏览器通过重新获取原始 URL 来处理循环永久重定向?
301 重定向不起作用,浏览器仍然缓存旧的 301 重定向,我看到无限循环
我是如何测试的:前段时间我确实为 http://www.SOMEHOST.com 做了 301 重定向到 https://www.SOMEHOST.com。但现在 http://www.SOMEHOST.com 必须是网站的主要主机。因此,从 https 重定向到 http 已删除。正如您所展示的,我确实将 301 从 https://www.SOMEHOST.com 重定向到 http://www.SOMEHOST.com,但请参阅循环。浏览器没有重新获取...
我确认,只要(显然)您删除了最初的 301 重定向,重定向(在我的情况下使用 PHP 重定向)在 Google Chrome 上完美运行。
我可以确认重定向返回工作正常。浏览器看到重定向循环使缓存条目无效。在 IE11、Firefox 52、Safari 10、Chrome 57 上测试。
H
Hugo

从铬 71

要清除永久重定向,请转到 chrome://settings/clearBrowserData 并从那里仅清除“缓存的图像和文件”清除重定向。

铬 48-70

转到 chrome://net-internals。在顶部红色状态栏的右侧,点击向下箭头 ▼ 打开下拉菜单,在“工具”组下,选择“清除缓存”。

从版本 48 开始,这是我清除缓存 301 的唯一方法。


从 Chrome 版本 54 开始,不幸的是,这对我不起作用。
再想一想,我并没有真正回答真正的问题,“浏览器缓存 301 需要多长时间”,而且我的回答对重定向面向公众的网站的任何人都无济于事,您可能需要某种方法来永久撤消 301在不知道有多少浏览器缓存了重定向的情况下——其他答案部分解决了这种情况。我的回答实际上只对开发人员或您可以与所有受影响用户进行通信的 Intranet 场景有用。
适用于 Chrome 版本 68.0.3440.106(官方版本)
chrome://net-internals 在 Chrome 71 中已被删除。下拉/工具部分已消失。有一个 DNS > 主机解析器缓存 > 清除主机缓存按钮,但这对于删除缓存的 301 不起作用。
在 Chrome 71 中, chrome://settings/clearBrowserData 并从那里仅清除“缓存的图像和文件”即可清除重定向。
m
michaelmcandrew

一个可以帮助那些迫切希望摆脱重定向缓存的人的答案:

Chrome 会无限缓存 301 重定向(在本地磁盘缓存中)。要清除此缓存:

打开你的 DevTools(按 F12)

在“网络”选项卡上选中“禁用缓存”复选框

保持 DevTools 打开并重新加载页面(按 F5)

当一切正常时,您可以取消选中“禁用缓存”,一切都会按预期继续工作。


这有效,即使在重新启用缓存后重定向也消失了。谢谢!
看起来这不适用于通过本地主机文件指向 127.0.0.1 的域。这种情况还有其他选择吗?
如果重定向无意中指向另一个端口,例如从 localhost:8000localhost(端口 80),则不起作用。我还从 localhost 和 localhost:8000 清除了整个站点/应用程序数据,但这也没有帮助。
自 2019 年 11 月 16 日起,此解决方案适用于 Chrome 版本 78.0.3904.97。其他解决方案不再可用。让它工作后,你可以关闭开发者工具,它会继续正常工作。
接受的答案。
R
Rajesh Paul

有一种非常简单的方法可以删除 http 重定向的浏览器缓存,例如 301、307 等。

您可以在 chrome 的开发者控制台中打开网络面板。选择网络呼叫。右键单击它,然后单击清除浏览器缓存以删除缓存的重定向。

https://i.stack.imgur.com/MHj3k.png


非常感谢!简单的解决方案和工作!这种方式将来也应该有效。
K
Krtek Net

让用户在该网址上提交一个帖子表单,缓存的重定向就消失了:)

<body onload="document.forms[0].submit()">
<form action="https://forum.pirati.cz/unreadposts.html" method="post">
    <input type="submit" value="fix" />
</form>
</body>

我同意这是我找到的最好的拧开方法。
与其他答案不同,此方法适合在不打开开发者控制台的情况下解决其他人的问题!谢谢你
fetch('URL', {method: 'POST'}) 应该以同样的方式来实现。谢谢!这让我有些头疼!
我不敢相信这是对我有用的唯一方法(我首先尝试了所有其他方法 - 甚至控制台 fetch() 由于跨站点安全策略而失败)。
这对我不起作用(在 Android 的 Chrome 上测试)。用例:以前有 OpenWRT 路由器,它 301 重定向到 /cgi-bin/luci/。我不得不切换到不同的路由器,现在我只能在私人选项卡中访问它的 GUI,因为缓存的重定向。
A
Alex J

301 是每个 HTTP RFC 的可缓存响应,浏览器将根据响应中的 HTTP 缓存标头对其进行缓存。使用 FireBug 或 Charles 检查响应标头以了解响应将被缓存的确切持续时间。

如果您想控制缓存持续时间,您可以使用 HTTP 响应标头 Cache-ControlExpires 来做同样的事情。或者,如果您根本不想缓存 301 响应,请使用以下标头。

Cache-Control: no-store, no-cache, must-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT

虽然在技术上是正确的,但您的回答并没有回答用户的问题,因此也没有回答我来这里的问题。浏览器中已有的、未缓存的标头 301 何时会在主要浏览器中过期?
如果有人仍然感兴趣,this link 指令可以将缓存切换为 301。
该链接适用于FF,对我不起作用。安装 Web 开发者扩展 1.2.5 并使用 FF 23.0.1
没有回答这个问题。问题是,如果未指定到期日期,重定向将被缓存多长时间
E
Emeke Ajeh

确认的!!使用户向受影响的 url 提交 post 请求,并且缓存的重定向被遗忘。

如果可以的话,一个快速的胜利就是在浏览器控制台中输入这个:

fetch('example.com/affected/link', {method: 'post'}).then(() => {})

如果您知道受影响的浏览器(尤其是在开发期间),这很有用。

或者,如果您可以访问之前的 301 重定向页面,那么您可以将此脚本添加到该页面,并且无论何时访问它,缓存的 301 都会被遗忘。


这类似于上面的帖子形式,只是它更省力。
J
John Tribe

我将发布对我有帮助的答案:

转到网址:

chrome://settings/clearBrowserData

它应该调用弹出窗口,然后..

仅选择:缓存的图像和文件。

选择时间框:从头开始


在 Chrome 79 中工作!
T
T.Todua

出于测试目的(避免缓存重定向),人们可以打开NEW PRIVATE WINDOW:点击CTRL+SHIFT+N [如果您使用 Mozilla,请使用 {3 }]


这已被降级,可能是因为“私有窗口”的主要承诺不是写入缓存,但仍然可以读取/重用它们。但对我来说,在 Firefox 37.0.1 (Linux) 上这行得通,而且非常快速和有用。私人窗口反映了网络服务器的当前/未缓存设置,而普通浏览器选项卡使用缓存的 301 重定向。
alfonx:私有窗口可能不会重用缓存,因为服务器所有者可以以 cookie 的方式使用元素来揭示该用户以前的身份。尽管我必须承认缓存重用对于讨厌色情的妻子来说可能是安全的。
如果您已经有缓存的 301,这将不起作用。 Private 确实会使用缓存的重定向。
S
Stephen Ostermiller

作为@thomasrutter 的回答

如果您之前发出了 301 重定向但想取消该操作

如果人们在他们的浏览器中仍然有缓存的 301 重定向,那么无论源页面是否仍然有重定向,他们都会继续被带到目标页面。您解决此问题的选项包括:

最简单和最好的解决方案是再次发出另一个 301 重定向。

浏览器将意识到它正在被引导回它之前认为是已停用的 URL,这应该会导致它再次重新获取该 URL 以确认旧的重定向不存在。

如果您无法控制上一个重定向目标所访问的站点,那么您就不走运了。尝试请求网站所有者重定向回您。

事实上,这意味着:

a.example 301 到 b.example 删除 a.example 的 301 添加 b.example 301 到 a.example

然后它工作。


但是你仍然有 b.com 的 301 : ( - 一个肮脏的修复
您可以通过从 不同 页面发出另一个 301 来清除重定向吗?例如(a.com 301 -> b.com)(删除 a.com 的 301)(添加 a.com/abcdefg 301 -> a.com)并强制客户端以某种方式查看 a.com/abcdefg
谢谢它的作品!在 IE11、Firefox 52、Safari 10、Chrome 57 上测试
我有一种情况,想同时使用 a.com 和 b.com。所以 b.com 301 a.com 不是一个选择。我们的解决方案是迁移到 HTTPS——我们在 HTTPS 上没有重定向
如果你可以从 b 做 302,为什么要 301?
M
Mohammad Ersan

在最新的 Google Chrome 版本 79 上,您可以使用 chrome://net-internals 并从左侧面板中选择 DNS,然后点击清除主机缓存按钮

https://i.stack.imgur.com/6e1hX.png


E
EECOLOR

我有适用于所有主要浏览器(最新版本)的简单解决方案,包括 IE、Chrome 和 FF

Ctrl + Shift + Del - Chrome:选择“浏览历史记录”和“缓存...” IE:我保留默认选项“Internet 临时文件和网站文件”、“Cookie 和网站数据”、“历史记录”FF:“浏览和下载历史”、“缓存” 单击“删除” 关闭并重新打开您的浏览器。它应该工作


您还应该确保您不在相关页面上,因为某些浏览器不会从打开的页面中清除缓存的项目。
y
yunzen

正如其他答案所示。缓存在浏览器中可能是不确定的。这是极其危险的。所以不要这样做。至少添加缓存头。在 htaccess 中,我总是这样做,根本没有缓存:

<IfModule mod_rewrite.c>
  RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
  # The E=nocache:1 sets the environment variable nocache to the value of one
  RewriteRule ^/?(.*) https://www.example.org/$1 [L,R=301,E=nocache:1]
</IfModule>


<IfModule mod_headers.c>
  ## Set the response header if the "nocache" environment variable is set
  ## in the RewriteRule above.
  Header always set Cache-Control "no-store, no-cache, must-revalidate" env=nocache

  ## Set Expires too ...
  Header always set Expires "Thu, 01 Jan 1970 00:00:00 GMT" env=nocache
</IfModule>

编辑:

如果您过去没有缓存 301 重定向,则必须从目标重定向回源。例子:

如果你有这个

RewriteRule /my-source /my-target [L,R=301]

你需要把这个

# RewriteRule /my-source /my-target [L,R=301]
RewriteRule /my-target /my-source [L,R=301]

c
combatc2

为了解决本地主机地址的问题,我更改了站点运行的端口号。这适用于 Chrome 版本 73.0.3683.86。


y
yougotiger

使用隐身/InPrivate 模式测试您的重定向,这样当您关闭浏览器时,它将刷新该缓存,并且重新打开窗口将不包含缓存。


E
Ensai Tankado

在你的 .htaccess 文件中试试这个:

  <IfModule mod_expires.c>
  ExpiresActive On
  Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
  Header Set Cache-Control "max-age=0, no-store"
  Header Set Cache-Control "no-store"
  Header set Pragma "no-cache"
  </IfModule>

这将告诉访问您网站的浏览器不缓存任何内容,知道如何执行此操作很有用。问题是,如果您错误地从您的域发出了 301 重定向,可能是由于拼写错误,这些浏览器已经缓存了这些重定向,它们不会再次向您的站点发出请求,因此不会获得您的这些新标头有建议。
R
Rogach

移动 Chrome 的一个技巧(此处为 93 版):尝试以“桌面站点”模式打开 url - 这在我的情况下删除了永久缓存的重定向。


D
Daud khan

要禁用重定向,请将此代码放入重定向站点的索引文件中

<script>
    fetch('https://www.example.com', {method: 'post'}).then(() => {})
</script>