刷新动态路由时Sevltekit 404错误

Sevltekit 404 error when refreshing dynamic route

我想要一个基于URL动态加载内容的静态页面,例如: https://example.com/pokemon/id

它可以像单页应用一样加载到服务器端或客户端。

svelte.config.js

import adapter from '@sveltejs/adapter-static';

    export default {
        kit: {
            adapter: adapter({
                pages: 'build',
                assets: 'build',
                fallback: null
            }),
        }
    };

[id].svelte

<script context="module">
export const hydrate = false;
    import { getPokemonById } from "../../stores/pokestore";
    export async function load(ctx) {
        let id = ctx.page.params.id;
        const pokeman = await getPokemonById(id);
        return { props: { pokeman }}
    }
</script>
<script>
    export let pokeman;
    const type = pokeman.types[0].type.name;
</script>
<svelte:head>
    <title>Pokedex - {pokeman.name}</title>
</svelte:head>

<div class="flex flex-col items-center">
    <h1 class="text-4xl text-center my-8 uppercase">{pokeman.name}</h1>
    <p>Type: <strong>{type}</strong> | Height: <strong>{pokeman.height}</strong>
        | Weight: <strong>{pokeman.weight}</strong>
    </p>
    <img class="card-image" src={pokeman.sprites['front_default']} 
    alt={pokeman.name}
    />
</div>

如果进入主页并单击 link:

,则效果很好
<a href={`/pokeman/${pokeman.id}`}><h2>{pokeman.name}</h2></a>

但是如果我刷新这个页面我得到错误 404 因为这个页面不存在。

我无法在构建期间生成所有子页面,因为它们是动态的。

我在 Firebase 主机上托管这个网站。

这很可能是重定向问题。

当您从主页单击 link 时,您实际上并没有 'go' 到此页面,sveltekit 更改了 url 但您保持在同一页面上,您可以通过单击 'open in new tab'.

来查看

这里发生的事情是,当您直接转到该页面时,您的服务器找不到该页面,因此出现 404 页面。您需要设置一个重定向系统,将所有页面重新路由回根页面(sveltekit 路由将从那里获取它)。

如何设置取决于您的主机

Discord 上的 Svelte 社区帮助我解决了问题。

因为我在 Firebase 主机上托管网站,所以我必须在 firebase.json 中添加重写规则,如下所示:

"hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  },

如果它有帮助,这就是我在 Apache 服务器上的 .htaccess 文件中用来解决这个问题的方法:

# Redirect all to the index
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

刷新将加载 index.html 主页面,但仍保留之前的 url(这是不对的):domain.com/sample/url