解决Cloudflare Pages的308自动重定向功能

我在使用Cloudflare Pages的时候,发现了一个非常奇怪的问题,就是发布的带有.html后缀的网页,会自动308重定向到一个没有.html的地址,并且,这个行为是Cloudflare Pages底层硬编码,无法通过配置参数关闭。

这个问题我用中文咨询了所有主流AI,都没有得到好的解决,有给方案说,使用.htm代替.html,因为Cloudflare Pages不会重写.htm文件,但这对于老网站的SEO来说显然不行,还有一个方案说是使用 Pages 函数进行拦截,说将一段代码放入functions/[[path]].js 文件中,然后重新发布,然后就会返回 200 + HTML内容,不会再有308重定向的状态码。我按照其方法发布了,也不行。

接着,我使用Google搜索“Cloudflare Pages html 308 Permanent Redirect”这样的关键词,看到一大堆Cloudflare的用户反馈同样的问题,但每一个问题都没有给出解决方案,翻了好几页也没找到解决方法。

后来,我用Google Translate将我原先的问题翻译为英文,然后提交给Google Gemini,这时候Gemini给出了一个全新的方案,这是以前没见过的,我按照这个新方案试了一下,竟然成功了,使用 curl -I URL,得到的回应从308变成200了,再访问网页,也没有再跳转了,看来还是英文AI更靠谱啊。

这个解决方案,通过使用Cloudflare Pages 函数(中间件)绕过308重定向限制,在重定向发生之前拦截请求,在内部获取HTML,并将其连同200 OK状态一起返回给浏览器。

下面就是保留.html扩展名的解决方案:

1、在项目根目录(与输出/构建目录同级,但不要位于其内部)创建一个文件夹functions。

2、在它里面创建一个名为_middleware.js的文件。

3、添加以下代码以拦截.html请求:

JavaScript代码如下:

export async function onRequest(context) {
const url = new URL(context.request.url);
// 1. Check if the incoming request is for an .html file
if (url.pathname.endsWith('.html')) {
// 2. Remove the .html extension for the internal lookup
url.pathname = url.pathname.slice(0, -5);
// 3. Clone the original request (to keep headers) but use the new URL
const newRequest = new Request(url.toString(), context.request);
// 4. Fetch the extension-less asset internally.
// This returns the 200 HTML response directly to the browser.
return context.env.ASSETS.fetch(newRequest);
}
// For all other requests, proceed to normal Cloudflare routing
return context.next();
}

这种方法的原理是,当用户请求.html页面时,此中间件会捕获该请求,这个函数会在后台秘密地向 Cloudflare 请求不带扩展名的页面路径,然后,它会获取成功的HTML 响应,并将其直接发送回原始URL,这时候,旧永久链接将立即加载,无需任何重定向跳转。

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论