把表单的目标地址放在请求里,把代理放在连接配置里。代理不需要一个装着目标 URL 的特殊表单字段,除非你使用的是某个网站自带的网页代理界面。

对于 Ruby 的 Net::HTTP,可以在创建客户端时指定一个显式的 HTTP 代理:

require 'net/http'

uri = URI('https://example.com/form')
http = Net::HTTP.new(uri.hostname, uri.port,
                     '203.0.113.10', 8080)
http.use_ssl = true
http.open_timeout = 5
http.read_timeout = 10
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data('message' => 'hello')
response = http.start { |session| session.request(request) }

这里的代理只是示例;用于获准公开表单测试的 HTTP 候选代理可在HTTP 代理列表中找到。表单端点必须替换为专门接收提交的服务。Net::HTTP 的代理文档还说明了代理凭据和从环境变量中取得的代理设置。

先读响应,再怪代理

表单被服务器拒绝时,即使代理线路本身工作正常,也可能返回 HTTP 错误。要检查响应状态和目标端的要求:请求方法、内容类型、表单字段、Cookie 以及任何请求令牌。

代理身份验证挑战来自代理本身。应用登录或表单被拒则属于目标端。两者的凭据要分开保存。把目标端的密码写进代理配置,并不能满足目标端的登录。

Squid 的转发头规则是另一个容易混淆的地方。它属于服务器端的策略,与构造一个合法的 Ruby POST 是两回事。不要因为表单失败过一次就去改动共享代理的头规则。

重试之前,先考虑第一次提交是否可能已经被处理。响应丢失并不能证明 POST 从未到达应用。

相关文章