如何在 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.host
、Request.path
和Request.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.uri
或 request.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 的结果
如何在客户端上保存 JWT 令牌,在节点中使用 Hapi js。?
Cakephp3:如何在询问标记后使用get参数获取当前页面的完整URL