使用 WinHttp 发布表单

Posted

技术标签:

【中文标题】使用 WinHttp 发布表单【英文标题】:Posting form using WinHttp 【发布时间】:2011-05-30 15:04:17 【问题描述】:

在向服务器发帖之前我需要添加任何标题吗?

例如,目前我正在尝试以这种方式发送请求以及发布数据,

  LPCWSTR post = L"name=User&subject=Hi&message=Hi";

    if (!(WinHttpSendRequest( hRequest, 
                            WINHTTP_NO_ADDITIONAL_HEADERS,
                            0, (LPVOID)post, wcslen(post), 
                            wcslen(post), 0)))
    
          //error
    

这应该有效吗?

【问题讨论】:

【参考方案1】:

什么对我有用:

    LPSTR  post = "log=test";//in my php file: if(isset($_POST['log']))
    hRequest = WinHttpOpenRequest(hConnect,
                                    L"POST",
                                    L"/test.php",
                                    NULL,
                                    WINHTTP_NO_REFERER,
                                    WINHTTP_DEFAULT_ACCEPT_TYPES,
                                    0);
    bResults = WinHttpSendRequest(hRequest,
                                    L"content-type:application/x-www-form-urlencoded",
                                    -1,
                                    post,
                                    strlen(post),
                                    strlen(post),
                                    NULL);

【讨论】:

【参考方案2】:

我猜

您需要传递不宽的窄字符串作为发布数据。我不知道您是否为发布的数据指定了一种内容类型,该类型将指定编码 - 如果容易的话,您可能应该这样做 - 或者只是将字符串重新编码为 UTF-8,或者只是组装为一个窄字符串首先 您可能需要在帖子数据上明确添加行尾,即将\r\n 添加到您的(窄)字符串中 - 我不知道 API 是否会添加一个,因为我假设您会对二进制数据的相同调用。

【讨论】:

我使用LPCSTR 发布并添加了\r\n,但它仍然返回表单url 源代码本身而不是发布它。它以前对我有用过 libcurl。 为了设置cookies,我使用WinHttpAddRequestHeaders,它接受LPCWSTR作为标题字符串。例如:"Cookie: session=key" 完成! 1.) 我需要用www. 指定站点 2.) 我需要使用窄字符串。 3.) \r\n 不是必需的。 但是,post 数据不接受分号 ';'在消息字符串中。相反,它在分号之前发送消息部分,并在“;”之后忽略消息的后半部分。无论如何要发送';'? 帖子数据以 URL 编码字符串的形式发送,因此您需要将 ; 写为 %3B。除字母、数字和少数其他字符之外的字符应写为 %,然后是两位数的十六进制值。这是在RFC1738 中指定的,但它不是很可读。您应该能够在 C++ 中找到现有的 URL 编码函数,您可以在这里使用,或者这里有人的 test encode / decode page 可以尝试。对 \r\n 红鲱鱼感到抱歉!【参考方案3】:

根据这个MSDN page,假设您在WinHttpOpenRequest 中使用了"POST" 动词,那么您的代码示例肯定可以工作。如果一切都不起作用,那么在网络浏览器和您的应用程序上运行 Fiddler,并比较两种情况生成的标头。

【讨论】:

好吧,不- lpOptional 参数是一个缓冲区,而不是一个宽字符串,所以他将字符串作为服务器可能不期望的 unicode 数据传输。而且他正在传递 API 期望字节长度的字符串字符长度,因此在任何情况下他都只传输一半的字符串。 @Rup 是的,你是对的,wcslen 会给出字符数,而不是缓冲区大小。半根绳子很像半只蜜蜂......

以上是关于使用 WinHttp 发布表单的主要内容,如果未能解决你的问题,请参考以下文章

如何异步使用“WinHttp.WinHttpRequest.5.1”?

如何从 WinHttp 请求中获取 HTTP 状态码?

WinHttp.WinHttpRequest 添加到内容类型

wininet 或 winhttp,这是 POST 请求的首选

如何取消同步 WinHttp 请求?

WinHttp Delphi 包装器