使用经典 ASP VBScript 时无法获取原始 POST 数据
Unable to get raw POST data when using Classic ASP VBScript
我已经尝试了两天来设置满足第 3 方提供商要求的端点。他们将通过 HTTPS POST 向我们发送有关业务对象状态的更新,请求的内容将是 JSON。不幸的是,它现在必须用 VBScript 编写。
目前,我无法获得他们发送给我的请求的原始内容,所以我根本无法处理它。
我创建了一个简单的端点 (raw-form.asp) 和两个测试页面来演示该问题。首先,我使用 HTML 表单设置了一个简单的测试 HTML 页面 (raw-form-test1.asp),它工作正常。第二个测试页面 (raw-form-test2.asp) 使用 WinHttpRequest
将内容发送到端点。使用它时,数据不存在。我正在尝试通过 Request.Body
.
获取它
原始格式-asp:
<%
Dim post : post = Request.Body
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
%>
原始格式-test1.asp:
<!DOCTYPE html>
<html>
<body>
<form action="raw-form.asp" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
原始格式-test2.asp:
<%
Dim data : data = Request.Form("data")
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:8080/raw-form.asp"
http.Send data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
%>
<!DOCTYPE html>
<html>
<body>
<%= Server.HTMLEncode(resp) %>
<form action="raw-form-test2.asp" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
当填写一些随机文本并提交第一个测试时,响应正文如我所料:
Your POST data was: data=abc
使用第二个测试时,resp
中的返回结果为:
200 | Your POST data was:
我也尝试过使用 Request.BinaryRead()
但没有成功(VB 脚本得到它的长度,但不是内容 - 可能只是 VB 对类型很糟糕)。我希望有另一种获取数据的方法。
在 raw-form.asp 中,你可以 Response.BinaryWrite Request.BinaryRead 的结果,像这样:
<%
If Request.TotalBytes > 0 Then
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: "
Response.BinaryWrite Request.BinaryRead(Request.TotalBytes)
End If
%>
或者您可以使用 Request.BinaryRead,然后将字节写入 ADO 流对象,然后您可以从中读取文本。这是来自的示例:
<%
If Request.TotalBytes > 0 Then
Dim lngBytesCount, post
lngBytesCount = Request.TotalBytes
post = BytesToStr(Request.BinaryRead(lngBytesCount))
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
End If
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "iso-8859-1"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
%>
仍然 trying to understand 最大的问题是什么,假设您的端点 returns JSON 您可以修改我发布的示例代码中的以下过程。
Sub http_post()
Dim data : data = Request.Body
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:1337/test9.asp?action=2"
Call http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
http.Send "data=" & data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
'Interpret the response from the xhr as JSON.
Response.ContentType = "application/json"
Call Response.Write(http.ResponseText)
End Sub
Sub http_xhr()
Dim post : post = Request.Body
Response.ContentType = "application/json"
%>{
data: {
"SomeItem": "SomeData",
"SomeNumber": 1,
"PostedData": "<%= post %>"
}
}<%
End Sub
%>
我刚刚测试了您的代码并对其进行了一些重组,以便我可以使用一个文件对其进行测试,它做同样的事情。
<%
Dim data, method
Call init()
Sub init()
Dim action
method = UCase(Request.ServerVariables("REQUEST_METHOD") & "")
Select Case method
Case "GET"
Call http_get()
Case "POST"
action = Request.QueryString("action") & ""
If Len(action) > 0 And IsNumeric(action) Then action = CLng(action) Else action = 1
Select Case action
Case 1
Call http_post()
Case 2
Call http_xhr()
End Select
End Select
End Sub
Sub http_get()
%>
<!DOCTYPE html>
<html>
<body>
<form action="?action=1" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
<%
End Sub
Sub http_post()
Dim data : data = Request.Form("data")
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:1337/test9.asp?action=2"
'We are mimicing a form post use x-ww-form-urlencoded.
Call http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
'Need to make sure we pass this as "data=value" so we can use `Request.Form("data") in the xhr call.
http.Send "data=" & data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
Call Response.Write(resp)
End Sub
Sub http_xhr()
Dim post : post = Request.Form("data")
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
End Sub
%>
使它起作用的主要区别是;
- 在 xhr 上设置
Content-Type
header 以便我们可以调用 Request.Form
(实际上与 Request.Body
一起使用,我的新版本).
- 将数据作为
data=value
编码值传递给 xhr。
我已经尝试了两天来设置满足第 3 方提供商要求的端点。他们将通过 HTTPS POST 向我们发送有关业务对象状态的更新,请求的内容将是 JSON。不幸的是,它现在必须用 VBScript 编写。
目前,我无法获得他们发送给我的请求的原始内容,所以我根本无法处理它。
我创建了一个简单的端点 (raw-form.asp) 和两个测试页面来演示该问题。首先,我使用 HTML 表单设置了一个简单的测试 HTML 页面 (raw-form-test1.asp),它工作正常。第二个测试页面 (raw-form-test2.asp) 使用 WinHttpRequest
将内容发送到端点。使用它时,数据不存在。我正在尝试通过 Request.Body
.
原始格式-asp:
<%
Dim post : post = Request.Body
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
%>
原始格式-test1.asp:
<!DOCTYPE html>
<html>
<body>
<form action="raw-form.asp" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
原始格式-test2.asp:
<%
Dim data : data = Request.Form("data")
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:8080/raw-form.asp"
http.Send data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
%>
<!DOCTYPE html>
<html>
<body>
<%= Server.HTMLEncode(resp) %>
<form action="raw-form-test2.asp" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
当填写一些随机文本并提交第一个测试时,响应正文如我所料:
Your POST data was: data=abc
使用第二个测试时,resp
中的返回结果为:
200 | Your POST data was:
我也尝试过使用 Request.BinaryRead()
但没有成功(VB 脚本得到它的长度,但不是内容 - 可能只是 VB 对类型很糟糕)。我希望有另一种获取数据的方法。
在 raw-form.asp 中,你可以 Response.BinaryWrite Request.BinaryRead 的结果,像这样:
<%
If Request.TotalBytes > 0 Then
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: "
Response.BinaryWrite Request.BinaryRead(Request.TotalBytes)
End If
%>
或者您可以使用 Request.BinaryRead,然后将字节写入 ADO 流对象,然后您可以从中读取文本。这是来自的示例:
<%
If Request.TotalBytes > 0 Then
Dim lngBytesCount, post
lngBytesCount = Request.TotalBytes
post = BytesToStr(Request.BinaryRead(lngBytesCount))
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
End If
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "iso-8859-1"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
%>
仍然 trying to understand 最大的问题是什么,假设您的端点 returns JSON 您可以修改我发布的示例代码中的以下过程。
Sub http_post()
Dim data : data = Request.Body
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:1337/test9.asp?action=2"
Call http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
http.Send "data=" & data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
'Interpret the response from the xhr as JSON.
Response.ContentType = "application/json"
Call Response.Write(http.ResponseText)
End Sub
Sub http_xhr()
Dim post : post = Request.Body
Response.ContentType = "application/json"
%>{
data: {
"SomeItem": "SomeData",
"SomeNumber": 1,
"PostedData": "<%= post %>"
}
}<%
End Sub
%>
我刚刚测试了您的代码并对其进行了一些重组,以便我可以使用一个文件对其进行测试,它做同样的事情。
<%
Dim data, method
Call init()
Sub init()
Dim action
method = UCase(Request.ServerVariables("REQUEST_METHOD") & "")
Select Case method
Case "GET"
Call http_get()
Case "POST"
action = Request.QueryString("action") & ""
If Len(action) > 0 And IsNumeric(action) Then action = CLng(action) Else action = 1
Select Case action
Case 1
Call http_post()
Case 2
Call http_xhr()
End Select
End Select
End Sub
Sub http_get()
%>
<!DOCTYPE html>
<html>
<body>
<form action="?action=1" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
<%
End Sub
Sub http_post()
Dim data : data = Request.Form("data")
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:1337/test9.asp?action=2"
'We are mimicing a form post use x-ww-form-urlencoded.
Call http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
'Need to make sure we pass this as "data=value" so we can use `Request.Form("data") in the xhr call.
http.Send "data=" & data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
Call Response.Write(resp)
End Sub
Sub http_xhr()
Dim post : post = Request.Form("data")
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
End Sub
%>
使它起作用的主要区别是;
- 在 xhr 上设置
Content-Type
header 以便我们可以调用Request.Form
(实际上与Request.Body
一起使用,我的新版本). - 将数据作为
data=value
编码值传递给 xhr。