POST http://localhost:3000/api/auth/login 404 (Not Found)
Unexpected token '<', "<!DOCTYPE "... is not valid JSON
apiFetch
嘗試 JSON.parse()
,但伺服器回來的是 HTML(以 <!DOCTYPE html>
開頭)。:3000
,但不是我那個 Express app 的 /api/auth/login
。:3000
,回了 HTML(像 SPA 的 index.html
)。export const API_BASE = "http://localhost:3000";
const data = await apiFetch('/api/auth/login', {
method: 'POST',
body: JSON.stringify({
// 若後端預期 usernameOrEmail,這裡要對齊
usernameOrEmail: username.value,
password: password.value
})
});
if (!username && !password)
改成 if (!username || !password)
(小地方但對的)。path
一定用 /api/...
(要有前導 /
)。// server/index.js
app.use('/api/auth', authRouter); // prefix 正確
// server/routes/userAuth.js
router.post('/login', handler); // 不要再寫成 '/api/auth/login'
export default router;
→ 最終端點應該是 POST /api/auth/login
。
我在最上面加了一個 logger:
app.use((req, _res, next) => {
console.log('REQ', req.method, req.path);
next();
});
REQ POST /api/auth/login
。http://localhost:3000/api/ping
得到 200,卻也沒印 REQ GET /api/ping
。換一個埠來驗證
4000
:
// server/index.js
const port = 4000;
export const API_BASE = 'http://localhost:4000';
http://localhost:4000/api/ping
REQ GET /api/ping
。列出實際有掛的路由(dev only)
app.get('/__routes', (_req, res) => {
const routes = [];
app._router.stack.forEach((layer) => {
if (layer.route) {
routes.push({
path: layer.route.path,
methods: Object.keys(layer.route.methods).map(m => m.toUpperCase())
});
} else if (layer.name === 'router' && layer.handle.stack) {
layer.handle.stack.forEach((r) => {
if (r.route) {
routes.push({
path: r.route.path,
methods: Object.keys(r.route.methods).map(m => m.toUpperCase())
});
}
});
}
});
res.json(routes);
});
http://localhost:4000/__routes
"/login"
(POST
),代表 router 有掛好。先加一個「已知可達」的最小路由(排除 router import 問題)
// 先直接在 server/index.js 補一條
app.post('/api/auth/login', (req, res) => {
res.json({ ok: true, reached: true, body: req.body || null });
});
REQ POST /api/auth/login
,userAuth.js
的匯入 / 導出或子路徑有誤。必要時找出佔用 3000 的進程
ss -ltnp | grep :3000
# 或
lsof -i :3000
/api/*
會被 index.html
吞掉。credentials: 'include'
+ 後端 cors({ origin, credentials: true })
兩邊都要設。usernameOrEmail
,前端就別送 username
。<!DOCTYPE html>
」= 你在解析 HTML 當 JSON,通常是 404/錯伺服器/錯掛載。