【问题标题】:How to know if a request is http or https in node.js如何知道 node.js 中的请求是 http 还是 https
【发布时间】:2012-05-08 02:23:48
【问题描述】:

我正在使用 nodejs 和 expressjs。我想知道 clientRequest 对象中是否有类似request.headers.protocol 的东西。我想为 Web 链接构建 baseUrl。因此,如果请求是通过 https 完成的,我想在所有链接中保留 https。

    var baseUrl = request.headers.protocol + request.headers.host;

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    编辑: 对于 Express,它更安全,建议使用 req.secure(如下面的 @Andy 建议)。虽然它使用类似的实现,但它对将来的使用是安全的,并且它还可以选择支持 X-Forwarded-Proto 标头。

    话虽如此,对于您的用例,使用 Express 的 req.protocol 属性(httphttps)会更快。但是请注意,对于传出链接,您只需引用//example.com/path,浏览器将使用当前协议。 (另见Can I change all my http:// links to just //?

    对于没有 Express 的节点 Request 对象:

    req.connection.secure(布尔值)中。

    编辑: 对于 Node 0.6.15+,API 已更改:

    HTTPS 连接具有req.connection.encrypted(包含有关 SSL 连接信息的对象)。 HTTP 连接没有req.connection.encrypted

    另外(来自the docs):

    使用 HTTPS 支持,使用 request.connection.verifyPeer() 和 request.connection.getPeerCertificate() 获取客户端的身份验证详细信息。

    【讨论】:

    • 在最新的节点 0.10 及更高版本中是否仍然可用?
    • 嗯,您能否为以后的节点版本(如 0.8 及更高版本)验证这一点,我在文档中找不到任何此类内容。但可能是我读错地方了。
    • 至少when using express,可以依赖req.secure(作为布尔属性)或同样的'https' == req.protocol
    • 我正在运行 NodeJs v11.5.0 并且请求对象不包含 .connection.encrypted -- 我现在怎么知道?
    • 试试req.socket.encrypted。在最新版本的 Node.js 中,.connection 属性已更改为 .socket 属性。 nodejs.org/dist/latest-v12.x/docs/api/…
    【解决方案2】:

    req.securereq.protocol === 'https' 的简写,应该是你要找的。​​p>

    如果您在代理后面运行您的应用,请启用“信任代理”,以便 req.protocol 反映用于在客户端和代理之间进行通信的协议。

    app.enable('trust proxy');

    【讨论】:

    • 哦,对,和require('url').parse(..).protocol混淆了
    • 很高兴提及app.enable('trust proxy'); 不使用它会导致重定向循环。
    • @Ben node v5.x 和这个有什么关系?请阅读 express 4.x 的文档(这是迄今为止最新的):expressjs.com/en/4x/api.html#req.protocol
    【解决方案3】:

    你不需要在 URL 中指定协议,因此你不需要为这个问题而烦恼。

    如果您使用<img src="//mysite.comm/images/image.jpg" />,如果页面以 HTTP 提供,浏览器将使用 HTTP,如果页面以 HTTPS 提供,则浏览器将使用 HTTPS。在另一个线程中查看the @Jukka K. Korpela explanation

    【讨论】:

    • 谢谢 Gerardo,你是对的,但是对于这个项目,我需要检测协议。
    • 但这不适用于通用应用程序,在服务器上您必须指定协议
    【解决方案4】:

    对于纯 NodeJS(这在本地工作和部署,例如在 Nginx 后面):

    function getProtocol (req) {
        var proto = req.connection.encrypted ? 'https' : 'http';
        // only do this if you trust the proxy
        proto = req.headers['x-forwarded-proto'] || proto;
        return proto.split(/\s*,\s*/)[0];
    }
    

    【讨论】:

      【解决方案5】:

      如果您想知道请求是 http 还是 https,请在您的代码中使用:

      req.headers.referer.split(':')[0];
      

      这将返回 req 是 http 还是 https。

      【讨论】:

      • 它只在用户从同一个站点重定向时有效,当使用直接在浏览器导航栏中输入域访问该站点时,它不起作用
      【解决方案6】:

      这对我有用:

      req.headers['x-forwarded-proto']
      

      希望这有帮助,

      E

      【讨论】:

      • 请注意,这仅在您的应用程序在设置此标头的反向代理后面运行时才有效 - 这是一个好主意,但可能并非如此,尤其是在例如本地开发环境。 (另外,请记住,如果您在代理后面,客户端可能会欺骗标头,因此请小心您如何信任它。)
      • 另外,在某些情况下,这会为您提供 ip 而不是 http 主机!
      • 我正在使用 OpenShift,这是该服务的正确答案(req.secure 和 req.protocol 不起作用);只是想我会提一下,以防其他人也是。
      【解决方案7】:

      这对我有用:

      getAPIHostAndPort = function(req, appendEndSlash) {
          return (req.connection && req.connection.encrypted ? 'https' : 'http') + '://' + req.headers.host + (appendEndSlash ? '/' : '');
      }
      

      【讨论】:

        【解决方案8】:

        如果您正在使用请求模块,例如想知道某些 www 使用什么协议,您可以使用:response.request.uri.protocol

        request(YOUR_TARGET, function(error, response, body){
            if (error){
                console.log(error);
            }
            else {
                console.log(response.request.uri.protocol); // will show HTTP or HTTPS
            }
        });
        

        如果您需要用户协议,请使用 request.headers.referer.split(':')[0]; 就像 @Harsh 给你的那样。

        【讨论】:

          【解决方案9】:

          如果您使用的是 Nginx 等代理服务器,您应该在其配置文件中设置 proxy_set_header X-Forwarded-Proto https;,因此如果您使用的是 TSL,express 可以将 https 识别为 req.headers['x-forwarded-proto'] 值或将 true 识别为 req.secure

          【讨论】:

            【解决方案10】:

            如果要查找请求协议字符串:http 或(对于 TLS 请求)https 只需使用

             req.protocol
            

            快递文档:https://expressjs.com/en/4x/api.html#req.protocol

            【讨论】:

              猜你喜欢
              • 2012-01-02
              • 1970-01-01
              • 2017-06-16
              • 2019-07-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-20
              • 1970-01-01
              相关资源
              最近更新 更多