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

时间:2015-08-05 18:37:48

标签: url hapijs

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

+----------+------------+
|  Field   |  DataType  |
+----------+------------+
| NoteId   | AutoNumber |
| ParentId | Long       |
| NoteDate | Date/Time  |
| NoteNext | Memo       |
+----------+------------+

我发现我可以将它与Public Sub MigrateNotes() Dim db As DAO.Database Dim rsDest As DAO.Recordset Dim rsSource As DAO.Recordset Dim nId As Long Dim aNotes() As String Dim n As Long Dim dtDate As Date Dim sNote As String On Error GoTo EH DoCmd.Hourglass True Set db = CurrentDb db.Execute "DELETE * FROM temp_Notes" Set rsDest = db.OpenRecordset("SELECT * FROM temp_Notes") Set rsSource = db.OpenRecordset("SELECT RowId,Diary FROM SourceNotes") With rsSource Do Until .EOF nId = .Fields("RowId").Value aNotes = parseNotes(.Fields("Diary").Value) For n = 0 To UBound(aNotes) dtDate = CDate(Left(aNotes(n), 10)) sNote = Right(aNotes(n), Len(aNotes(n)) - 11) With rsDest .AddNew .Fields("RowId").Value = nId .Fields("NoteDate").Value = dtDate .Fields("NoteText").Value = sNote .Update End With Next 'n .MoveNext Loop End With MsgBox "Complete" GoTo FINISH EH: With Err MsgBox .Number & vbCrLf & .Source & vbCrLf & .Description .Clear End With 'for debugging purposes Debug.Assert 0 GoTo FINISH Resume FINISH: DoCmd.Hourglass False On Error Resume Next 'release resources If Not rsDest Is Nothing Then rsDest.Close Set rsDest = Nothing End If If Not rsSource Is Nothing Then rsSource.Close Set rsSource = Nothing End If End Sub Private Function parseNotes(ByVal sRaw As String) As String() Dim nYear As Long Dim sYearToken As String Dim nIndex As Long Dim nSkip As Long For nYear = 1999 To Year(Date) sYearToken = "/" & nYear & " " 'use 12 to skip past first date ("mm/dd/yyyy " = 11) nSkip = 12 Do 'find the end of the date nIndex = InStr(nSkip, sRaw, sYearToken) If nIndex > 0 Then 'find the start of the date nIndex = nIndex - 6 sRaw = Left(sRaw, nIndex) & vbCrLf & Right(sRaw, Len(sRaw) - nIndex) 'use 12 to skip past next date nSkip = nIndex + 12 End If Loop Until nIndex <= 0 Next 'n parseNotes = Split(sRaw, vbCrLf) End Function function getRequestUrl (request) { return ...; // What goes here? } Request.info.host分开,但它缺少方案(即http vs https),并且是一点点kludge。是不是可以在某处获得普通URL?

4 个答案:

答案 0 :(得分:35)

完整的网址不会存储在您可以获取的地方。你需要自己从部分构建它:

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

即使它看起来像kludgey,但如果您考虑它是有道理的,因为没有原始的,未解析的,未修改的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请求的主机头解析的request.info.host

代理和X-Forwarded-Proto标题

如果您的请求通过代理(负载)/负载均衡器/ HTTPS终结器传递,则可能会在某处沿着HTTPS流量终止并通过HTTP连接发送到您的服务器,在这种情况下,您可以#39;如果它在那里,请使用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}`;

答案 1 :(得分:1)

hapi-url解决了这个问题。它准备使用X-Forwarded标头在代理后面运行。如果库无法正确解析URL,还可以选择覆盖自动解决方案。

答案 2 :(得分:0)

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

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);
});

它为您提供了用户请求的确切网址。

答案 3 :(得分:0)

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

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