使用传统ASP VBScript时无法获取原始POST数据
我一直在尝试两天来设置符合第三方提供程序要求的端点。他们将通过HTTPS POST向我们发送关于业务对象状态的最新信息,请求内容将为JSON。不幸的是,它现在必须用VBScript编写。使用传统ASP VBScript时无法获取原始POST数据
目前,我无法获得他们发送给我的请求的原始内容,所以我无法处理它。
我已经创建了一个简单的终端(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()
没有成功(VBScript中获得获得它的长度,而不是内容 - 可能只是VB类型的可怕)。我希望有另一种方式来获取数据。
在原始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流对象,然后你可以从中读取文本。下面是一个例子:https://stackoverflow.com/a/9777124/989516
<%
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
%>
他们正在做一个标准的'HTTP POST'没有理由他们不能使用'Request.Form'我有的问题是他们似乎说他们使用'Request.Body'但在经典ASP中没有这样的属性'Request'对象。 – Lankymart
天才!谢谢...这就像一个魅力。我曾尝试让'BinaryRead'工作,但不知道我必须开始使用Streams来读取它。我依稀记得另一个使用类似技术处理多部分表单数据的VBScript库。 – BoffinbraiN
@Lankymart我认为如果您没有指定(正确或忽略)POST请求的实际类型,VBScript的Request.Form停止工作。因此,获取原始请求数据是必要的。 – BoffinbraiN
不过trying to understand的大问题是什么,假设您的端点返回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
头,所以我们可以称之为Request.Form
(与Request.Body
,对我新的实际工作)。 - 将数据传递给xhr作为
data=value
编码值。
谢谢你试图帮助,但凯文柯林斯已经解决了这个问题。再次澄清,*我是必须编写端点的人。第三方发布给它。我无法控制他们使用的内容类型。我写的测试页面就是模拟这个问题。事实证明,他们使用'application/json'这就是为什么'Request.Form'和'Request.Body'不起作用的原因。 – BoffinbraiN
@BoffinbraiN这清除它,对不起,我以为你发送到端点和你模拟在。毫无意义的答案,但无论如何将离开它,可能会帮助某人。 – Lankymart
根据第三方端点的设置方式,我不希望POST请求返回的结果不是'HTTP 200 OK'或更好的结果'HTTP 201 Created'。确定要返回的内容的唯一方法是在测试代码时运行Fiddler。大多数*(不是全部)*基于HTTP的端点使用RESTful设计原则,阅读这些原则可能会帮助您理解为什么除了'HTTP 200 OK'之外什么都看不到。它可能在你没有看到的响应中有一个“位置”标题,因为你正在尝试检查正文。 – Lankymart
这可能是有趣的*(假设它是RESTful)* - [了解REST:动词,错误代码和身份验证](// stackoverflow.com/a/2022938) – Lankymart
我刚刚意识到您的示例并不是说到第三方端点时,忽略我所说的问题可能是您在'raw-form-test2.asp'中调用了'Request.Form(“data”)'但是它假设来自哪里?当然,你只是想要一些测试数据一串或什么?如果通过表单提交调用该页面,则只会在Request.Form中获取某些内容。 – Lankymart