| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- 'use strict';
- // 迷你路由(零依赖):
- // const app = createRouter();
- // app.get('/api/job/:id', handler); // :段 提取参数
- // app.any('/api/reports/status', h); // 不限方法(保持旧行为)
- // app.fallback(serveStatic); // 未命中路由时兜底
- // http.createServer((req, res) => app.dispatch(req, res));
- // 处理器签名:async ({ req, res, pathname, query, params }),异常由错误边界统一响应。
- const { errorBoundary } = require('./middleware.js');
- const { sendJson } = require('./util.js');
- function toSegments(pattern) {
- return pattern.split('/').filter(Boolean)
- .map((seg) => (seg.startsWith(':') ? { name: seg.slice(1) } : seg));
- }
- function createRouter() {
- const routes = [];
- let fallbackHandler = null;
- function add(method, pattern, handler) {
- routes.push({ method, segments: toSegments(pattern), handler: errorBoundary(handler) });
- }
- return {
- get: (p, h) => add('GET', p, h),
- post: (p, h) => add('POST', p, h),
- del: (p, h) => add('DELETE', p, h),
- any: (p, h) => add('*', p, h),
- fallback: (fn) => { fallbackHandler = fn; },
- async dispatch(req, res) {
- let pathname;
- let searchParams;
- try {
- const parsedUrl = new URL(req.url, `http://${req.headers.host}`);
- pathname = parsedUrl.pathname;
- searchParams = parsedUrl.searchParams;
- } catch {
- res.writeHead(400);
- return res.end('bad url');
- }
- const query = Object.fromEntries(searchParams);
- const parts = pathname.split('/').filter(Boolean);
- let pathMatched = false;
- for (const route of routes) {
- if (route.segments.length !== parts.length) continue;
- const params = {};
- let ok = true;
- for (let i = 0; i < parts.length; i++) {
- const seg = route.segments[i];
- if (typeof seg === 'string') {
- if (seg !== parts[i]) { ok = false; break; }
- } else {
- params[seg.name] = parts[i];
- }
- }
- if (!ok) continue;
- pathMatched = true;
- if (route.method !== '*' && route.method !== req.method) continue;
- return route.handler({ req, res, pathname, query, params });
- }
- if (pathMatched) return sendJson(res, 405, { error: 'Method Not Allowed' });
- if (fallbackHandler) return fallbackHandler(pathname, res);
- res.writeHead(404);
- res.end('Not found');
- },
- };
- }
- module.exports = { createRouter };
|