只有在内容类型为html(或类似类型)时,软重定向才起作用。对于二进制文件,比如'foo.pdf',GitHub不会进行重定向,因为它会根据pdf扩展名设置mime类型,软重定向将被解释为损坏的pdf文件。
话虽如此,在GitHub上仍然有可能正确地进行重定向,但只有在满足以下条件时才使用以下解决方案:
- 服务器不允许您自己设置301重定向(例如GitHub页面)
- 文件扩展名设置了mime类型,并且是二进制文件(例如pdf、png等)
- 其他解决方案都不适用于您的情况
- 用户直接使用浏览器访问资源,而不是通过html引用(例如
<img src="...">
)
- 旧页面不再被Google等搜索引擎索引(即,站点地图指向新的URL),因为该解决方案会导致Google无法爬取资源(Google只会看到404错误)
- 您被允许提供自定义的404页面(例如GitHub页面)
关键是在404页面中使用嵌入的JavaScript来检查URL并进行相应的重定向。
GitHub Pages 允许您通过在项目的根目录中创建一个名为 "404.html" 的文件来定义 404 页面(假设整个项目通过分支部署;否则将文件放在部署构件的根目录中)。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data:; connect-src 'self'"
/>
<title>Page not found</title>
<style type="text/css" media="screen">
// style your 404 nicely
</style>
</head>
<body onload="redirect()">
<div class="container">
<h1>404</h1>
<p><strong>File not found</strong></p>
<p>The requested resource does not exist.</p>
<div id="suggestions">
<a href="/">Bring me back!</a>
</div>
</div>
</body>
<script>
function redirect() {
if (window.location.pathname === '/old_incorrect_path/foo.pdf') {
window.location = 'https://yourpage.com/path_to_correct_resource/foo.pdf';
}
}
</script>
</html>
嵌入的JavaScript在404页面加载后检查请求的路径名,并只有在匹配旧地址时才进行重定向。您可以通过链接多个资源来使用这种方式,通过链接多个if语句,或者如果是整个页面的完全重定向,则替换所有URL的位置主机(但在可能的情况下,请使用其他方法)。或者,您也可以将脚本放在顶部并立即执行,而不是等待完全加载,但是,对于用户来说,看到他们的链接确实是404然后将他们发送到正确的位置可能是很好的(这也是一个提醒,一旦人们直接访问正确的链接,您应该删除这个黑客方法)。
请注意,在404页面上设置"Content-Security-Policy"为大部分 'unsafe-inline' 是有意义的,因为您不应该在404页面上加载其他资源。
请在没有其他方法实现所需结果的情况下,不要使用此解决方案。再次强调,此方法仅在用户直接浏览资源时有效。此外,网络爬虫将将这些页面识别为404,因此不会将其视为有效的重定向。例如,谷歌不允许在从谷歌搜索控制台迁移域名时使用此方法(您需要使用301重定向或有效的软重定向通过来使谷歌接受迁移)。此外,通过img等方式引用资源也会中断(因为图像仅被视为404)。
然而,在某些情况下,这是一个有效的解决方案,例如用户直接访问资源而引荐者尚未更新链接(例如过时的谷歌搜索结果链接或其他链接到旧地址的页面)。他们的自动化工具(如果有的话)将通知他们链接返回404,并引导他们更新链接(希望最终能够更新)。