如何在Vanilla JavaScript中实现所有请求返回index.html构建SPA路由
解决Vanilla JS SPA路由直接访问路径返回404的问题
当你直接在地址栏输入/seller这类路径或刷新页面时,浏览器会向服务器发起对应路径的请求,但你的服务器上没有对应文件,所以返回Cannot GET /seller。要解决这个问题,核心是让服务器对所有路由请求都返回index.html,之后由前端路由逻辑处理页面内容。下面是不同服务器环境的配置方法:
1. Node.js + Express 环境
如果用Express搭建服务器,添加以下中间件捕获所有请求:
const express = require('express'); const path = require('path'); const app = express(); // 托管项目静态文件 app.use(express.static(path.join(__dirname, '你的项目根目录'))); // 所有请求返回index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '你的项目根目录', 'index.html')); }); app.listen(3000, () => console.log('服务器运行在 http://localhost:3000'));
2. Nginx 部署环境
修改Nginx配置文件,添加try_files指令:
server { listen 80; server_name 你的域名或IP; root /你的项目绝对路径; index index.html; location / { try_files $uri $uri/ /index.html; } }
配置后,Nginx会先尝试访问请求的文件/目录,不存在时自动返回index.html。
3. VS Code Live Server(开发环境)
如果用VS Code的Live Server插件开发,在项目根目录创建.live-server.json文件:
{ "mount": [["/", "/index.html"]] }
这样Live Server会把所有请求导向index.html,匹配前端路由逻辑。
你的前端路由逻辑无需修改,以下是你提供的代码:
router.js
const route = (event) => { event = event || window.event; event.preventDefault(); window.history.pushState({}, "", event.target.href); handleLocation(); }; const routes = { 404: "pages/404.html", "/": "pages/loginPage.html", "/seller": "pages/sellerPage.html", "/block-list": "pages/blockListPage.html", "/customer": "pages/customerPage.html", }; const handleLocation = async () => { const path = window.location.pathname; const route = routes[path] || routes[404]; const html = await fetch(route).then((data) => data.text()); document.getElementById("main-page").innerHTML = html; }; window.onpopstate = handleLocation; window.route = route; handleLocation();
index.html
<!doctype html> <html lang="ko"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vanilla JS SPA</title> </head> <body> <a href="/" onclick="route()">login</a> <a href="/seller" onclick="route()">seller</a> <div id="main-page"></div> <script src="router.js"></script> </body> </html>
内容的提问来源于stack exchange,提问作者myeongin
相关产品推荐
相关产品推荐

