1

尝试发送POST请求时遇到问题。发送方法如下所示:

Public Sub SendXML(ByVal file As String)
    Dim reader As New StreamReader(file)
    Dim data As String = reader.ReadToEnd()
    reader.Close()
    Dim request As HttpWebRequest = WebRequest.Create("http://blah/Request")
    request.Method = "POST"

    System.Net.ServicePointManager.Expect100Continue = False

    Dim bytes As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
    request.ContentLength = bytes.Length

    Dim oStreamOut As Stream = request.GetRequestStream()
    oStreamOut.Write(bytes, 0, bytes.Length)
    oStreamOut.Close()

    Dim response As HttpWebResponse = request.GetResponse()

End Sub

运行此程序时,我收到上述错误。通过 Fiddler 我可以看到请求看起来像:

POST http://blah/Request HTTP/1.1
Host: blah
Content-Length: 322
Proxy-Connection: Keep-Alive

<?xml version="1.0"?>
<Envelope>
<Header>
<UserID>uid</UserID>
<Password>pass</Password>
<SessionID />
<RequestType>GetDetails</RequestType>
<POSCompany>01</POSCompany>
<PackageType>DATA</PackageType>
<ActionType>READ</ActionType>
<SnoopUserID />
</Header>
<Body>
<MagicNumber>124</MagicNumber>
</Body>
</Envelope>

现在看这个我怀疑这是由于服务器不接受POST消息的事实。但是其他一些阅读表明 URIhttp://blah/Request是使用代理生成的,应该是/Request这样的行应该是POST /Request HTTP/1.1

那么常见的原因是什么?如果是代理问题,如何排序?

如下所述,我为更具体的请求创建了一个新问题。在 HTTP POST 标头中将绝对 URI 更改为相对

4

3 回答 3

1

POST 请求没有任何问题,所以问题肯定出在其他地方。

沿途还有许多其他地方可能会造成麻烦:

  1. 您和正在更改 HTTP 方法的服务器之间可能存在错误代理
  2. 服务器可能出现故障或根本不支持 POST

然而,我的猜测是,服务器所做的不仅仅是查看 HTTP 方法,而是给您一个 405 错误以响应您的 XML 有效负载正在包装的 RPC 调用。

一些 RPC 服务器将(错误地)使用这样的 HTTP 状态代码来指示请求的方法无法执行,或者请求具有权限和安全性质的其他问题。

如果服务器表现得稍微好一点(你很幸运),它应该在响应正文中返回可能指示 405 错误来自何处的附加信息。

于 2012-04-04T16:37:26.033 回答
0

您是否缺少Content-Typea 所需的标题POST?阅读此处了解详细信息。我认为这是强制性的。

于 2012-04-11T04:34:33.167 回答
0

您的 POST 似乎完全无效。POST 数据应该被编码(即,作为 multipart/form-data)并使用正确的内容类型(即 application/x-www-form-urlencoded)和适当的编码和边界等。你只是向服务器发送一个一堆文字,我并不惊讶它会翻出来。

我不是 100% 确定 VB 在幕后做什么,但这个 MSDN 页面建议您需要将内容类型设置为受支持的方法,并且您可能也需要Content-Disposition: form-data在标题中。我找到了一个这样做并添加 MIME 边界的示例:

string FileData = "this is test file data\r\n"; // test data to send.
StringBuilder DataString = new StringBuilder();
DataString.Append(dataBoundary + "\r\n");
//This sends the viewstate info
DataString.Append("Content-Disposition: form-data; name=" + HiddenValue
+ "\r\n"
+ dataBoundary + "\r\n");
DataString.Append("Content-Disposition: form-data; name=" + "\"" +
"File1" +
"\"" +
"; filename=" + "\"" + "TestFile3.txt" + "\"" + "\r\n");
DataString.Append("Content-Type: text/plain\r\n\r\n");
DataString.Append(FileData);
DataString.Append(dataBoundary + "\r\n");
DataString.Append("Content-Disposition: form-data; name=" + "\"" +
"Submit1" +
"\"" + "\r\n\r\n" + "Upload\r\n" + dataBoundary + "--\r\n");

该示例模拟文件字段上传。

对于更简单的版本,您可以使用request.ContentType = "application/x-www-form-urlencoded"URL 编码的数据,例如:Dim postData As String = "myURL=http%3A%2F%2Fexample.com%2Findex.php". 请注意,格式是key=value,并且数据必须首先进行 URL 编码。

我不确定您到底需要什么,因为很大程度上取决于远程服务器对表单和字段名称的实际期望。它还取决于服务器是否实际遵循相关的 HTML 标准和 RFC。您是否有一个有效的 HTML 表单可用作服务器期望的指南?

于 2012-04-11T04:59:38.533 回答