如何在不使用Express框架的情况下,基于http.createServer实现通配符路由
不用Express,纯用http.createServer实现通配符路由
嘿,我完全懂你想绕开Express,直接用Node.js原生http模块实现类似/:id这种通配符路由的需求~你之前写的代码里直接把req.url和/:id做全等判断肯定行不通,因为实际请求的URL是像/123、/abc这种具体路径,而不是占位符形式的/:id。咱们可以用正则表达式来做模式匹配,这其实也是Express这类路由库背后的核心思路哦。
基础实现:匹配根路径和单参数路径
先给你一个简单可行的版本,直接在请求处理函数里用正则判断:
const http = require('http'); http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html' }); const url = req.url; // 匹配根路径 / if (url === '/') { res.write('I am foo'); res.end(); } // 匹配 /xxx 格式的路径(xxx是任意非斜杠字符) else if (/^\/[^\/]+$/.test(url)) { // 提取id:去掉路径开头的斜杠 const id = url.slice(1); res.write(`I am foo with id ${id}`); res.end(); } // 处理所有未匹配的路径,返回404 else { res.writeHead(404, { 'Content-Type': 'text/html' }); res.write('404 Not Found'); res.end(); } }).listen(3000, () => { console.log("server start at port 3000"); });
这里的正则/^\/[^\/]+$/可以拆解一下:
^:匹配字符串的开头\/:匹配路径里的斜杠(因为斜杠在正则里是转义字符,所以要加反斜杠)[^\/]+:匹配一个或多个不是斜杠的字符,确保我们只匹配单层级的路径$:匹配字符串的结尾
这样就能准确捕获像/123、/user123这类符合/:id格式的请求啦。
更灵活的方案:抽象路由规则
如果以后需要加更多路由,直接写一堆if-else会很臃肿。我们可以把路由规则抽象成一个数组,每个规则包含匹配正则和对应的处理函数,扩展性更强,也更接近Express的写法:
const http = require('http'); // 定义路由规则数组:每个元素是 { 匹配正则, 处理函数 } const routes = [ { pattern: /^\/$/, handler: (req, res) => { res.write('I am foo'); res.end(); } }, { // 用捕获组把id提取出来 pattern: /^\/([^\/]+)$/, handler: (req, res, matches) => { // matches[1]就是正则捕获组里的id参数 const id = matches[1]; res.write(`I am foo with id ${id}`); res.end(); } } ]; http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html' }); const url = req.url; let isMatched = false; // 遍历所有路由规则,找到匹配的就执行对应的处理函数 for (const route of routes) { const matches = url.match(route.pattern); if (matches) { route.handler(req, res, matches); isMatched = true; break; } } // 没有匹配到任何路由时返回404 if (!isMatched) { res.writeHead(404); res.write('404 Not Found'); res.end(); } }).listen(3000, () => { console.log("server start at port 3000"); });
这个方案里,我们用正则的捕获组来提取参数,和Express里的req.params.id逻辑一致。以后要加新路由,只需要在routes数组里新增一个规则对象就行,维护起来方便很多。
其实本质上,Express的路由就是把/:id这种占位符转换成对应的正则表达式,再做匹配和参数提取,咱们现在就是手动实现了这个核心逻辑~
内容的提问来源于stack exchange,提问作者saltyLake
相关产品推荐
相关产品推荐

