【问题标题】:How to get a url as a param in Node.js?如何在 Node.js 中获取 url 作为参数?
【发布时间】:2017-04-07 14:38:51
【问题描述】:

代码:

app.get("/:url", function(req,res) {
    var url = req.params.url;
    res.send(url);
});

问题:

这不起作用。

如果我尝试:

http://localhost:3000/https://www.google.com

我明白了:

Cannot GET /https://www.google.com

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    你可以试试这个,使用正则表达式:

    var app = require('express')();
    
    app.get(/^\/(.*)/, function (req, res) {
    
        var url = req.params[0];
        res.send(url);
    
    });
    
    app.listen(3000, () => console.log('Listening on 3000'));
    

    当你运行时:

    curl http://localhost:3000/https://www.google.com
    

    服务器应该返回:

    https://www.google.com
    

    更新

    URL 中的冒号是否合法存在一些争议。

    详情请看这个问题:

    根据 RFC 3986,这是一个合法的 URL:

    http://localhost:3000/https://tools.ietf.org/html/rfc3986
    

    但请注意,虽然这也是合法的:

    http://localhost:3000/https://tools.ietf.org/html/rfc3986#section-3.3
    

    如果您在浏览器中输入该 URL,您的服务器将只获得:

    /https://tools.ietf.org/html/rfc3986
    

    在请求中。出于这个原因,虽然不是绝对必要的,但我仍然建议对您放入其他 URL 的 URL 进行 URL 编码 - 请参阅 Zac Delventhal 的答案。

    实验

    使用上面的代码示例,这个命令:

    curl http://localhost:3000/https://www.google.com/
    

    会输出这个:

    https://www.google.com/
    

    但是这个命令:

    curl 'http://localhost:3000/https://www.google.com/#fragment'
    

    会输出这个:

    https://www.google.com/
    

    请注意,我在上面使用单引号不是因为它们在这里是必需的 - 它们不是,请参阅:

    echo http://localhost:3000/https://www.google.com/#fragment
    

    但是为了表明哈希片段不会消失,因为它被 shell 视为注释,以防有人认为这可能是原因。即使使用引号也不会发送,并且可以使用curl-v 开关演示发生的情况:

    * Connected to localhost (127.0.0.1) port 3000 (#0)
    > GET /https://www.google.com/ HTTP/1.1
    > User-Agent: curl/7.35.0
    > Host: localhost:3000
    > Accept: */*
    

    正如您所见,哈希片段甚至没有通过 HTTP 发送,因此您的服务器甚至不可能知道它的存在。

    顺便说一句,这也表明在其他 URL 中使用未编码的 URL 不会弄乱任何代理,因为对代理服务器的 HTTP 请求会发送以下内容:

    GET https://www.google.com/ HTTP/1.1
    

    不是这个:

    GET /https://www.google.com/ HTTP/1.1
    

    所以他们不会混淆。 (注意斜线。)

    【讨论】:

    • @Coder1000 - 你可能想知道我不认为http://localhost:3000/https://www.google.com 是一个合法的 URL,因此可能存在一些基础设施(例如代理),如果他们期望它可能无法使用遵循规则的 URL。
    • @jfriend00 实际上冒号和斜杠在 URL 中都是合法的。例如参见:en.wikipedia.org/wiki/Template:Welcome
    • 您是否愿意显示说明 http://localhost:3000/https://www.google.com 是合法 URL 的规范参考?工作示例并不能证明它们遵循规范。与规范相比,许多非法的事情发生了。
    • 这是一个反例。在 Google 搜索页面上,所有搜索结果链接都是 Google 重定向链接(因此它们可以跟踪您点击的内容)并包含实际 URL 作为搜索页面中 URL 的参数(右键单击并复制链接以获取实际链接)。 Google 在其中对 :/ 进行了编码。如果这不是一种更好或更安全的做事方式,他们为什么要这样做?
    • @jfriend00 我假设我们在这里讨论的是冒号,因为显然斜线和点在 URL 中是合法的。请参阅RFC 3986, Section 3.3。您不能在相对 URL(这不是)中使用冒号,即使那样也只能在第一部分段中使用。在 Stack Overflow 和 Quora 上也有一些关于它的问题 stackoverflow.com/questions/1737575/are-colons-allowed-in-urlsquora.com/Is-it-safe-to-use-a-colon-in-the-path-of-a-URL
    【解决方案2】:

    这是因为 :/ 是用于构建 URL 的特殊字符。换句话说,它们不是 url-safe。如果您想将这些字符作为 URL 路径的一部分发送,使用默认的 Express 参数解析器,您必须 percent-encode 它们。

    用你现有的代码试试这个:

    curl http://localhost:3000/https%3A%2F%2Fwww.google.com
    

    你应该回来了:

    https://www.google.com
    

    另一种选择是使用查询参数而不是路径变量。将您的代码 sn-p 稍微修改为:

    app.get("*", function(req, res) {
        var url = req.query.url;
        res.send(url);
    });
    

    然后,您可以使用以下命令对其进行测试:

    curl http://localhost:3000?url=https://www.google.com
    

    你应该回来:

    https://www.google.com
    

    虽然我会说对这些字符进行百分比编码可能仍然是一个好主意,尽管 Express 可以通过这种方式很好地解析它们。这可能会导致未来出现奇怪的行为。

    还有一个选择是将 url 作为字符串发送到 POST 请求的正文中,但这可能不是 RESTful,具体取决于您的用例。

    【讨论】:

      猜你喜欢
      • 2023-01-20
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 2013-09-19
      • 2017-09-30
      • 2020-12-22
      • 2016-02-03
      相关资源
      最近更新 更多