问题 Link to heading

最近正在忙字节青训营的项目,今天想试着在 Vercel 上面部署一下试试,没成想遇到了种种问题。这篇文章主要就网页刷新 404 报错写一下。

我的网页使用 Vue3 + TypeScript + Vite 完成,部署 Vercel 一次成功。我的页面大致包括:

1/
2├── user
3	  ├── user1
4	  └── user2
5└── ...

假设网站为 https://example.com,进入后在里面进行任意操作都正常,但假如我进入了某个子页面 example.com/user,此时刷新界面就会发现只剩下 404 了1

404 page

原因在于,单页应用的链接是虚假的,具体实现原理可以见此链接。简言之,使用 window.history.pushState 即可改变当前页面的 url,但不触发 reloading。

很多现代框架都实现了 SPA,例如适配 Vue.js 的 vue-router 就是专门用于实现 SPA 的。我们通过使用 const router = useRouter() 拿到封装的路由对象,并通过 router.push 改变当前路由,vue-router 会根据路由加载不同的页面2

解决3 Link to heading

通过查看打包的文件,只有一个 index.html 作为入口。因此解决思路很简单,将对不上号的资源请求全部重定向到 index.html 即可,这里展示一下 nginx 的配置:

1location / {
2  try_files $uri $uri/ /index.html;
3}

这行命令将逐个尝试返回 $document_root$uri$document_root$uri/$document_root/index.html

另外对于 Vercel 来说,可以在工程根目录加上文件 vercel.json

1{
2  "rewrites": [{ "source": "/:path*", "destination": "/index.html" }]
3}

Vercel 会将其重写到 index.html 处。

参考 Link to heading