如何通过 Classic ASP POST 发送 referrer URL?
结论
Microsoft.XMLHTTP 使用面向浏览器客户端的 HTTP 栈,可能会限制或忽略 Referer 等受保护的请求头。因此,即使执行了:
objXmlHttp.setRequestHeader "Referer", "http://www.yourdomain.com/basket.asp"
实际请求中仍可能不包含这个请求头。
在 Classic ASP 服务端代码中,建议改用 MSXML2.ServerXMLHTTP.6.0。它用于服务器之间的 HTTP 通信,通常能正确发送显式设置的 Referer。
原代码的 POST 数据还存在另一个问题:secuitems 后面缺少 &,导致 secuphrase 被拼进了 secuitems 的值。
推荐实现
<%
Dim http
Dim postData
Dim secuString
Dim refererUrl
refererUrl = "http://www.yourdomain.com/basket.asp"
postData = _
"shreference=" & Server.URLEncode("SH20XXXX") & _
"&secuitems=" & Server.URLEncode(secuitems) & _
"&secuphrase=" & Server.URLEncode("yourphrase") & _
"&transactionamount=" & Server.URLEncode(transactionamount)
Set http = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
' resolveTimeout, connectTimeout, sendTimeout, receiveTimeout,单位均为毫秒
http.setTimeouts 5000, 5000, 10000, 10000
http.open _
"POST", _
"https://www.secure-server-hosting.com/secutran/create_secustring.php", _
False
http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
http.setRequestHeader "Referer", refererUrl
http.send postData
If http.status >= 200 And http.status < 300 Then
secuString = Trim(http.responseText)
If Len(secuString) = 0 Then
secuString = "Call to create_secustring Failed"
End If
Else
secuString = "Gateway returned HTTP " & _
http.status & " " & http.statusText
End If
Set http = Nothing
%>
主要改动是使用:
Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
而不是:
CreateObject("Microsoft.XMLHTTP")
原 POST 数据中的拼接错误
原代码包含:
"&secuitems=" & secuitems & "secuphrase=yourphrase"
secuitems 与 secuphrase 之间少了一个 &。实际发送的数据会类似于:
shreference=SH20XXXX&secuitems=某个值secuphrase=yourphrase&transactionamount=...
应改为:
"&secuitems=" & Server.URLEncode(secuitems) & _
"&secuphrase=" & Server.URLEncode("yourphrase")
这个错误不能直接解释为什么没有收到 Referer,但如果不修复,即使请求头发送成功,也可能导致安全字符串生成失败或内容错误。
为什么 X-Alt-Referer 没有效果
X-Alt-Referer 只是一个自定义 HTTP 请求头:
X-Alt-Referer: http://www.yourdomain.com/basket.asp
它与标准请求头不同:
Referer: http://www.yourdomain.com/basket.asp
只有 UPG 明确支持读取 X-Alt-Referer 时,这个请求头才有用。如果网关检查的是标准 Referer,发送自定义请求头无法通过验证。
仍然失败时应检查什么
先确认控制面板中配置的 URL 与请求头逐字符一致,特别是以下差异:
http://与https://www.yourdomain.com与yourdomain.com/basket.asp与/basket.asp/- 路径的大小写
- 显式端口号
- 查询字符串
- URL 是否发生跳转
如果 UPG 接口返回 HTTP 重定向,重定向后的请求可能不会保留原始 Referer。可以请技术支持确认,他们检查的是初始请求还是重定向后的请求,并让他们提供实际收到的完整请求头。
也可以暂时把请求发到自己控制的 HTTPS 测试端点,记录所有请求头,确认 ServerXMLHTTP 实际发送了什么。不能只因为 ASP 代码调用了 setRequestHeader,就认定该请求头一定已经发出。
如果 ServerXMLHTTP 仍不能满足要求
如果改用 ServerXMLHTTP 后问题依旧存在,原因通常不是 ASP 字符串拼接,而是服务器环境中的 MSXML、代理、安全策略或 TLS 配置。可以考虑:
- 使用允许设置
Referer的第三方 COM HTTP 组件; - 在服务器上通过受控封装调用 cURL;
- 编写一个小型 ASP.NET 或其他服务端代理,由它调用 UPG;
- 请 UPG 提供不依赖
Referer的验证方式,例如签名字段、共享密钥或来源 IP 校验。
Referer 不是可靠的安全凭据,因为客户端可以伪造它,部分 HTTP 组件也可能将其省略。如果网关支持签名参数或消息认证码,这类方式通常比依赖 Referer 更稳妥。
不要照搬 PHP 示例中的 CURLOPT_SSL_VERIFYPEER = 0。生产支付流程应保留服务器证书验证,否则会削弱 HTTPS 对中间人攻击的防护。
备注:内容仅供参考。
