首页 > 解决方案 > Node.js HTTP 服务器中的参数

问题描述

我正在尝试制作一个类似于 express 的简单 HTTP 模块来帮助学习如何使用 HTTP。

在使用 express 时,我经常使用以下参数:

app.get('/id/:id' (req, res) => {console.log(req.params.id); stuff})

我想知道-

  1. 是否可以只使用HTTP?
  2. 如果仅使用 HTTP 无法完成,那么您将如何创建它?

标签: node.jshttpserverparameters

解决方案


是的,但您需要手动处理它。

假设您正在使用节点的http模块,您正在寻找的信息在其中,req.url但它包括整个 url 路径。

例如,您要解析/id/:id,而浏览器正在向http://your.server/id/100?something=something. 那么 的值req.url将是:

/id/100?something=something

但是,如果您使用net模块从头开始编写 HTTP 模块,那么您需要知道 HTTP 请求的格式。基本上,HTTP 请求看起来像具有以下格式的文本文件:

GET /id/100?something=something HTTP/1.1
Host: your.server

标题部分以双换行符结尾。从技术上讲,它应该是\r\n\r\n\n\n也是可以接受的。您首先需要从协议(上面示例中的 GET,但可以是 POST、PUT 等)和 HTTP 版本号之间的请求的第一行获取 url。

对于任何有兴趣从头开始编写 HTTP 服务器的人,我总是推荐 James Marshall 的优秀文章:https ://www.jmarshall.com/easy/http/ 。它最初是在 90 年代后期编写的,但直到今天我还没有找到更清晰的 HTTP 协议摘要。我自己用它来编写我的第一个 HTTP 服务器。

现在您必须编写代码来100从字符串中提取 。

如果您是手动执行此操作,而不是尝试编写 Express 之类的框架,则可以这样做:

const matches = req.url.match(/id\/([^\/?]+)/);
const id = matches[1];

如果你想编写一个库来解释/id/:id模式,你可以做这样的事情(注意:不是优化的实现,它的表达方式也略有不同):

function matchRoute (req, route) {
    const [ urlpath, query ] = req.url.split('?'); // separate path and query
    const pathParts = urlpath.split('/');
    const routeParts = urlpath.split('/');
    let params = {};

    for (let i=0; i<pathParts.length; i++) {
        if (routeParts[i].match(/^:/)) { // if route part starts with ":"
            // this is a parameter:
            params[routeParts[i].replace(':','')] = pathParts[i];
        }
        else {
            if (routeParts[i] !== urlParts[i]) {
                return false; // false means path does not match route
            }
        }

        // if we get here (don't return early) it means
        // the route matches the path, copy all found params to req.params:

        req.params = params;
        return true; // true signifies a match so we should process this route
    }
}

// Test:
let req.url = '/id/100';
let result = matchRoute(req, '/id/:id');
console.log(result, req.params); // should print "true, {id:100}"

推荐阅读