如何进行非缓存的301重定向?

13

一段时间以前,所有浏览器都改变了它们的行为并开始缓存301重定向,我想知道如何在PHP中实现不被缓存的301重定向?


5
为什么浏览器不应该缓存301重定向,既然它们从定义上是永久的?...我知道,业务可能会改变主意! - cspolton
Core Xii的回答是正确的。但是除此之外,您还可以使用Firefox/Chrome开发者工具插件来清除重定向和DNS缓存。 - Petah
1
将“永久”解释为“永恒”,在一个临时的世界、工作、公司、心态等中,是非常无知的。这里 - Timo Huovinen
避免301重定向缓存 - Timo Huovinen
1
请使用307,这是用于临时重定向的... - inf3rno
@cspolton 看起来“永久”的定义存在很大的差异,所以让我们来看看幕后的实现并与之合作。 - Timo Huovinen
2个回答

36

301是一种永久性重定向,因此缓存是有意义的。如果您的重定向不是永久性的,请使用307(临时重定向)、302(找到)或303(查看其他)。

在此处查看适当的用例。

对于这三者之间的区别作进一步说明:

  • 307是当资源移动时的通用临时重定向。例如,像domain.com/news/latest这样的 URL 可能会对最新的新闻文章进行 307 重定向,指向domain.com/news/article-594873 。由于该暂时重定向可能存在一段时间(该特定文章可能会是最新的几个小时),浏览器可能会缓存重定向。要控制缓存程度,请使用缓存控制头。
  • 303是绝不能被缓存的重定向。例如,将新文章发布到domain.com/news,可能会创建一个新的新闻文章,并提供到domain.com/news/article-978523的 303 重定向。由于另一个POST请求会导致创建完全不同的新文章,因此不能缓存。
  • 302有点奇怪,我自己从未使用过它。显然,对于早期的 HTTP 1.0 版本客户端不理解 303 的情况下,它更像是一个遗留的 303 替代品。

由于您特别询问了 PHP:

<?php
function header_redirect_permanent($url)
    {
    header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently', true, 301);
    header('Location: ' . $url);
    }

function header_no_cache()
    {
    header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // past date to encourage expiring immediately
    }

如果必须的话,您可以使用上述缓存控制头来防止代理缓存301,方法如下:

header_no_cache();
header_redirect_permanent($url);

或者简单地添加

header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Location:'.$url, true, 301);
exit;

1
但是有没有可能防止301被缓存,或者控制它的缓存时间,也许使用缓存头? - Timo Huovinen
3
为了让搜索引擎承载更多链接权重,但仍能够更改重定向。 - Timo Huovinen
1
如果您希望保留更改重定向的能力,那么它就不是“永久”的,对吧?我们的网络建立在非常规的标准上,这些标准说明301是“永久”的。请不要试图通过滥用协议来进行一些不光彩的“SEO”实践,来破坏我们的网络。 - Core Xii
1
这些目的并不可疑,如果我认为这样做是正确的,我有权利滥用协议,理论上可以控制301重定向的缓存吗?是或否? - Timo Huovinen
1
@TimoHuovinen:我已经测试了设置头部的解决方案,它非常好用。我建议接受这个答案,这样core-xii就可以得到积分了。 - wizonesolutions
显示剩余5条评论

5

没有缓存的http状态码301可以用于URL规范化,同时保留跟踪功能。

为了防止301重定向被缓存,请设置缓存控制头,然后您可以撤消重定向,客户端(机器人和浏览器)将不会再被重定向。

header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Location:'.$url, true, 301);
exit;

当您希望浏览器更新书签中的URL和机器人更新索引,但仍能够跟踪它们或通过将重定向返回到原始URL而不会导致无限循环或其他荒谬行为时,这非常有用。

这并不意味着301代码必须用于所有重定向,相反,不同类型的重定向具有不同的状态码Core Xii总结了这些状态码。


由于Core Xii在他的答案中提供了完全相同的信息(在你“自己回答问题”之前),你应该给予他信用,并评论或编辑他的答案会更好。另外,您可能正在为SEO优化的(良好的)机器人也了解缓存控制。因此,像不可缓存的302/307一样使用301将最多为您提供未缓存的302/307的好处,而在最坏的情况下,会因为做出被视为不诚实的行为而受到惩罚。 - Arkaine55

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接