PAYATHON 2026

如何通过 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 对中间人攻击的防护。

备注:内容仅供参考。