# コードレビュー依頼:pixelstomotors.com の古い住所の 301 転送 対象:Cloudflare Workers の worker/index.js(差分を下に貼る)。サイトは Astro で作った静的ファイルを Workers の静的アセット(env.ASSETS)から返している。wrangler.jsonc の run_worker_first は ["/*", "!/_astro/*", "!/site/*", "!/og/*", "!/thumbs/*", "!/embeds/*", "!/sim/*", "!/favicon*"] なので、ページへのリクエストは必ず worker の fetch() を通る。 ## やろうとしていること 検索エンジン・AI のクローラーが古い住所で読みに来て 404 になっているもののうち、行き先がはっきりしているものだけを 301 で今のページへ転送する。 | 来た住所 | 転送先 | 理由 | |---|---|---| | /manga と /manga/ | /manga-archive | 4コマの一覧は /manga-archive。/manga という一覧ページはない(/manga/ep01 などの各話はある) | | /manga/ep9 のような1桁 | /manga/ep09 | 話数の住所は2桁。クローラーが1桁で来ている | | /english-4-koma/ep9 のような1桁 | /english-4-koma/ep09 | 同上(英語版) | | /record/precision-is-not-learning | /record/precision-is-not-learning-so101 | 記事の住所の末尾が変わっていた | | /prototype1〜6(末尾の / もあり) | /series1〜6 | 前はシリーズのページの住所が /prototypeN だった(サイトの持ち主が確認済み) | 転送しないもの(404 のまま):/ai-agent(今は使っていないページ)、記事に載せたコードの文字列を住所と勘違いしたもの(/files/LOG395/{c} など)。 ## 差分 ```diff diff --git a/worker/index.js b/worker/index.js index 2c44687..df03666 100644 --- a/worker/index.js +++ b/worker/index.js @@ -26,6 +26,13 @@ export default { if (url.pathname.startsWith('/api/') || url.pathname.startsWith('/media/') || url.pathname === '/pixelstomotors' || url.pathname.startsWith('/pixelstomotors/')) { return secured(await route(request, env, url)); } + // 古い住所・まちがった住所への訪問を、今のページへ恒久転送する(2026-10-30。クローラーの「返せなかったページ」から) + const moved = movedTo(url.pathname); + if (moved) { + const to = new URL(moved, url); + to.search = url.search; + return Response.redirect(to.toString(), 301); + } const res = await env.ASSETS.fetch(request); // 検索エンジン・AI のクローラーが読みに来たか(記録の失敗でページを止めない) try { @@ -40,6 +47,23 @@ export default { }, }; +// 転送先の決まった古い住所。今は使っていないページ(/ai-agent。Dify で AI エージェントを動かしていた頃のもの)は転送しない(404 のまま) +const MOVED = { + '/manga': '/manga-archive', + '/manga/': '/manga-archive', + '/record/precision-is-not-learning': '/record/precision-is-not-learning-so101', +}; +function movedTo(path) { + if (MOVED[path]) return MOVED[path]; + // シリーズのページは、前は /prototype1〜6 だった(エイイチ 2026-10-30)。同じ番号の /series へ + const sp = path.match(/^\/prototype([1-6])\/?$/); + if (sp) return `/series${sp[1]}`; + // 4コマの話数は2桁(ep09)。1桁(ep9)で来たら0を付けた住所へ + const m = path.match(/^\/(manga|english-4-koma)\/ep([1-9])$/); + if (m) return `/${m[1]}/ep0${m[2]}`; + return ''; +} + async function route(request, env, url) { // 旧 URL の形(/pixelstomotors/…)で来たら、/pixelstomotors を外した URL へ恒久転送する if (url.pathname === '/pixelstomotors' || url.pathname.startsWith('/pixelstomotors/')) { ``` ## 手元で確かめたこと(Node で worker を読み込み、env.ASSETS をまねて fetch を呼んだ) - /manga → 301 /manga-archive、/manga/ → 301 /manga-archive - /manga/ep9 → 301 /manga/ep09、/english-4-koma/ep9?x=1 → 301 /english-4-koma/ep09?x=1(クエリは残す) - /manga/ep09・/manga/ep10・/record/precision-is-not-learning-so101・/manga-archive は転送されず、そのまま返る - /ai-agent は転送されない - /prototype1 → 301 /series1、/prototype6/ → 301 /series6、/prototype3?a=1 → 301 /series3?a=1、/prototype7・/prototype10 は転送されない - 注意:1桁の話のうち、実際にページがあるのは manga が8話分・english-4-koma が6話分。ない話は転送先でも 404 になる(転送前と結果は同じ) ## レビューしてほしいこと A1. 転送の条件(完全一致と正規表現)が、意図しない住所まで転送しないか(例:/manga/ep90、/manga-archive、/manga/ep9/ のような末尾スラッシュ) A2. 転送のループが起きないか(転送先が再び転送されないか。html_handling は auto-trailing-slash) A3. 転送先が存在しない 1桁の話(例 ep08 がない場合)を 301 にするのは問題か。存在を確かめてから転送すべきか B1. 既存の動き(/api/・/media/・/pixelstomotors/ の旧形式の転送・クローラーの記録・静的アセット)を壊していないか。転送したリクエストはクローラーの記録に残らなくなるが、問題か B2. 301(恒久)でよいか。あとで戻すことになったときの影響(ブラウザ・検索エンジンのキャッシュ) C1. 上の表以外に、転送すべき・すべきでない住所の判断で気になる点 各項目を ✅ OK/⚠️ 要注意(何が懸念か)/❌ NG(該当行と修正案)で答え、最後に「公開してよいか」「公開前に直すべき項目」をまとめてください。