如何在 Hapi 中获取请求的完整 URL

Posted

技术标签:

【中文标题】如何在 Hapi 中获取请求的完整 URL【英文标题】:How to get the full URL for a request in Hapi 【发布时间】:2015-10-28 16:31:06 【问题描述】:

在我的 hapijs 应用中,给定 Request object,我如何才能找到原始的、未解析的、未修改的 URL?

function getRequestUrl (request) 
    return ...; // What goes here?

我发现我可以将Request.info.hostRequest.pathRequest.query 拼凑起来,但它缺少方案(即http 与https),而且有点杂乱无章。纯 URL 不是在某处可用吗?

【问题讨论】:

【参考方案1】:

现在只有request.url:

https://hapi.dev/api?v=20.2.0#-requesturl

【讨论】:

【参考方案2】:

hapi-url 解决了这个确切的问题。它准备与 X-Forwarded 标头一起在代理后面运行。如果库无法正确解析 URL,还有一个选项可以覆盖自动解析。

【讨论】:

干得好。一些建议: 1. 当你重写resolve 原型方法时,通过Object.defineProperty 使其不可枚举。 2. 给HapiUrl.init添加一个空检查。您已经进行了类型检查,但由于 typeof null === "object",如果您调用 HapiUrl.init(null),您将收到运行时错误。 我不明白你所说的“让它不可枚举”是什么意思。你能提供更多细节吗?我在 GitHub 上创建了一个问题来讨论这个问题:github.com/rigon/hapi-url/issues/1【参考方案3】:

完整的 URL 未存储在您可以获取的位置。您需要自己从部件中构建它:

const url = request.connection.info.protocol + '://' + request.info.host + request.url.path;

即使它看起来很笨拙,但如果您考虑一下它还是有道理的,因为没有原始的、未解析的、未修改的 URL。例如,通过网络传输的 HTTP 请求不包含在浏览器地址栏中键入的 URL:

GET /hello?a=1&b=2 HTTP/1.1      // request.url.path
Host: localhost:4000             // request.info.host
Connection: keep-alive
Accept-Encoding: gzip, deflate, sdch
...

而且你只知道基于 hapi 服务器连接是否处于 TLS 模式(request.connection.info.protocol)的协议。

注意事项

如果您选中其中一个:

request.connection.info.urirequest.server.info.uri

报告的主机名将是运行服务器的实际机器的主机名(*nix 上hostname 的输出)。如果您想要该人在浏览器中键入的实际主机(可能不同),您需要检查从 HTTP 请求的 Host 标头解析的 request.info.host

代理和 X-Forwarded-Proto 标头

如果您的请求通过代理/负载平衡器/HTTPS 终结器,则可能在某处 HTTPS 流量被终止并通过 HTTP 连接发送到您的服务器,在这种情况下,您需要使用x-forwarded-proto 标头的值(如果存在):

const url = (request.headers['x-forwarded-proto'] || request.connection.info.protocol) + '://' + request.info.host + request.url.path;

使用模板字符串:

const url = `$request.headers['x-forwarded-proto'] || request.connection.info.protocol://$request.info.host$request.url.path`;

【讨论】:

request.connection.info.protocol 不是很好的解决方案。如果您需要更好地使用协议,请使用request.headers['x-forwarded-proto'] @Petroff 谢谢,用关于代理的注释更新了我的答案。 @MattHarrison request.info.host 给了我 localhost 而不是域名,但是在'x-forwarded-server': 'my-domain-com' 中得到它你能解释一下为什么吗? 不适用于最新的hapi 版本。但hapi-url 确实如此,请参阅 rigon 的回答。【参考方案4】:

您无法获取网址。你必须生成它。我正在使用这个:

const url = request.headers['x-forwarded-proto'] + '://' +
            request.headers.host + 
            request.url.path;

【讨论】:

【参考方案5】:

我现在使用以下语法(使用咖啡脚本):

server.on 'response', (data) ->
  raw = data.raw.req
  url = "#data.connection.info.protocol://#raw.headers.host#raw.url"
  console.log "Access to #url"

或者作为javascript

​server.on('response', function(data) 
  var raw = data.raw.req;
  var url = data.connection.info.protocol + "://" + 
  raw.headers.host + raw.url;
  console.log("Access to " + url);
);

这将为您提供用户请求的确切 URL。

【讨论】:

以上是关于如何在 Hapi 中获取请求的完整 URL的主要内容,如果未能解决你的问题,请参考以下文章

如何在自动创建的 API Rest Hapi 之前获取 validateFunc 的结果

获取 WKWebView 的当前完整 URL

如何在客户端上保存 JWT 令牌,在节点中使用 Hapi js。?

Cakephp3:如何在询问标记后使用get参数获取当前页面的完整URL

如何在不使用日志库的情况下记录对 hapi 服务器的所有请求?

如何在 Express 中获取完整的 URL?