【问题标题】:Send a POST message with UTF-8 special char with Wininet使用 Wininet 发送带有 UTF-8 特殊字符的 POST 消息
【发布时间】:2020-01-02 16:35:18
【问题描述】:

我想使用 Wininet 在 PHP 页面上发送消息。我的代码实际上与 UTF-8 特殊字符(如 €、é、à)不兼容。如何转换它?我搜索了很长时间,但没有找到解决方案。我尝试使用 wstring 但同样的问题。这是源代码:

void sendHello()
{
    LPCSTR header = "Content-Type: application/x-www-form-urlencoded; charset=utf-8";
    std::string dataStr = "message=ééàà€€";
    LPVOID myMessage = (LPVOID)dataStr.c_str();
    HINTERNET hInternet = InternetOpenA("InetURL/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    HINTERNET hConnection = InternetConnectA(hInternet, "127.0.0.1", 80, " ", " ", INTERNET_SERVICE_HTTP, 0, 1);
    HINTERNET hRequest = HttpOpenRequestA(hConnection, "POST", "/SendMessage.php", NULL, NULL, NULL, 0, 1);
    HttpSendRequestA(hRequest, header, strlen(header), myMessage, dataStr.size());
}

我发布了一个新问题,因为有人发布了一个类似的问题,但问题没有解决,并且所提出的解决方案不起作用。 (这是打开一个新问题的 StackOverflow 建议)。 感谢@Barmak、@Shemirani、@Unheilig、@Daniel Widdis 保持开放。

【问题讨论】:

  • 查看HttpSendRequestA 的文档,A 代表 ANSI。有一个 Unicode 版本的 API,其中函数以 W 结尾,例如支持 UTF-16 字符串的 HttpSendRequestW
  • @Romen 适用于lpszHeaders 参数,但不适用于lpOptional 参数,它采用任意数据并按原样发送,因为它可能是二进制的。 HttpSendRequestA 很乐意在 POST 正文中发送 UTF-8 数据。我怀疑真正的问题可能是std::string 在运行时实际上没有像OP 所期望的那样在运行时进行UTF-8 编码。确保编译器设置为以 UTF-8 格式保存源代码文件和字符串文字数据。此外,显示的字符串数据未正确进行 url 编码。 HttpSendRequestA 不会为你做 url-encoding,你必须自己做
  • @RemyLebeau,好点,他们可以使用std::string myString = u8"abcdé"; syntax for string literals 来强制使用UTF-8 编码,对吗?只要代码本身保存为 UTF-8 编码...
  • 我已经尝试过HttpSendRequestW 并且问题是一样的。此外,即使我使用std::string myString = u8"abcdé"; 声明字符串,char 也没有正确编码。
  • @ErwanZAMBA "char 编码不正确" - 那么你的项目有更大的问题需要追踪

标签: c++ string post utf-8 wininet


【解决方案1】:

谢谢大家,这是最终的解决方案:

void sendHello()
{
    LPCSTR header = "Content-Type: application/x-www-form-urlencoded; charset=utf-8";
    std::string dataStr = u8"message=ééàà€€";
    LPVOID myMessage = (LPVOID)dataStr.c_str();
    HINTERNET hInternet = InternetOpenA("InetURL/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    HINTERNET hConnection = InternetConnectA(hInternet, "127.0.0.1", 80, " ", " ", INTERNET_SERVICE_HTTP, 0, 1);
    HINTERNET hRequest = HttpOpenRequestA(hConnection, "POST", "/SendMessage.php", NULL, NULL, NULL, 0, 1);
    HttpSendRequestA(hRequest, header, strlen(header), myMessage, dataStr.size());
}

【讨论】:

    【解决方案2】:

    您没有正确地对字符串数据进行 url 编码。非 ASCII 和保留字符需要进行字符集编码为字节,然后将生成的字节编码为 %HH 格式。

    ééàà€€ 的 UTF-8 编码形式是字节

    C3 A9 C3 A9 C3 A0 C3 A0 E2 82 交流 E2 82 交流

    所以改变这个

    std::string dataStr = "message=ééàà€€"; 
    

    到这里

    std::string dataStr = "message=%C3%A9%C3%A9%C3%A0%C3%A0%E2%82%AC%E2%82%AC";`
    

    【讨论】:

    • 感谢您的回答,但同样的问题。
    • @ErwanZAMBA 那么问题不在于您显示的代码
    猜你喜欢
    • 1970-01-01
    • 2012-12-23
    • 2015-09-21
    • 2014-06-15
    • 2015-06-07
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 2015-05-28
    相关资源
    最近更新 更多