在我的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?
答案 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.uri
或request.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;