You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:52:39