Detailed Explanation and Solutions for Chinese Parameter Encoding Issues in HTTP POST Requests

When developing network applications using C++ (especially with the Qt framework), it is common to encounter issues when sending data containing Chinese characters to a server via the HTTP POST method. If encoding is not handled correctly, the receiving end often experiences garbled text. This article will delve into the causes of this common issue and provide a complete solution based on Qt, including detailed code examples and explanations of the principles involved.

1. Background: Why Does Chinese Text Become Garbled?

The HTTP protocol is designed based on the ASCII character set, which cannot directly transmit non-ASCII characters (such as Chinese, Japanese, special symbols, etc.). When we send data in the POST request body using <span>application/x-www-form-urlencoded</span> format (i.e., the common <span>key1=value1&key2=value2</span> form), all non-ASCII characters must be URL encoded (Percent-Encoding) to be transmitted and parsed correctly.

For example:

  • Original string: <span>测试中文</span>
  • Correctly URL encoded: <span>%E6%B5%8B%E8%AF%95%E4%B8%AD%E6%96%87</span>

If UTF-8 encoded Chinese byte sequences are directly concatenated into the request body (e.g., <span>"name=测试中文"</span>), the server will interpret them as illegal or incorrectly encoded byte sequences, resulting in garbled text.

2. The Principle of URL Encoding (Percent-Encoding)

URL encoding is a mechanism that converts special characters into a format that can be transmitted over the Internet, represented as a <span>%</span> followed by two hexadecimal digits. The rules are as follows:

  • ASCII letters, numbers, and characters such as <span>-_.~</span> remain unchanged;
  • Spaces are typically encoded as <span>+</span> (in form submissions) or <span>%20</span>;
  • All other characters (including Chinese) are first converted to byte sequences according to the specified character set (usually UTF-8), and then each byte is encoded as <span>%XX</span>.

For example:


"测" → UTF-8 bytes: E6 B5 8B → URL encoded: %E6%B5%8B

Therefore, the correct approach is to first convert the string to UTF-8 bytes, and then perform Percent Encoding on these bytes.

3. Solution in Qt: <span>toPercentEncoding()</span>

Qt provides a very convenient API to accomplish this:


QByteArray QString::toUtf8()const;
QByteArray QByteArray::toPercentEncoding(
const QByteArray &exclude =QByteArray(),
const QByteArray &include =QByteArray(),
char space ='%'
)const;

Recommended Usage:


QString content ="测试中文";
QString encoded = content.toUtf8().toPercentEncoding();

This line of code accomplishes two key steps:

  1. <span>toUtf8()</span>: Converts QString (internally UTF-16) to a UTF-8 encoded <span>QByteArray</span>;
  2. <span>toPercentEncoding()</span>: Performs standard URL encoding on the UTF-8 byte array.

⚠️ Note: Do not directly call <span>toPercentEncoding()</span> on <span>QString</span>, as this function defaults to using Latin-1 encoding, which will cause Chinese characters to become garbled!

4. Complete Code Example: Sending a POST Request with Chinese Parameters

Below is a complete example of using Qt’s <span>QNetworkAccessManager</span> to send a POST request containing Chinese parameters:


#include<QCoreApplication>
#include<QNetworkAccessManager>
#include<QNetworkRequest>
#include<QNetworkReply>
#include<QUrl>
#include<QUrlQuery>
#include<QDebug>

// Helper function: URL encode a single QString (UTF-8)
QString urlEncode(const QString &str){
return QString::fromLatin1(str.toUtf8().toPercentEncoding());
}

int main(int argc, char *argv[]){
    QCoreApplication app(argc, argv);

// Create network manager
    QNetworkAccessManager manager;

// Construct POST data (application/x-www-form-urlencoded)
    QString name ="张三";
    QString message ="你好,世界!这是测试中文。";

// Correctly encode Chinese
    QString postData = QString("name=%1&message=%2")
.arg(urlEncode(name))
.arg(urlEncode(message));

qDebug() << "Encoded POST data:" << postData;

// Set request
    QNetworkRequest request(QUrl("https://httpbin.org/post"));
    request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");

// Send POST request
    QNetworkReply *reply = manager.post(request, postData.toUtf8());

// Connect signal-slot to handle response
    QObject::connect(reply, &QNetworkReply::finished, [&](){
if(reply->error() == QNetworkReply::NoError){
qDebug() << "Response:" << reply->readAll();
}else{
qDebug() << "Error:" << reply->errorString();
}
        reply->deleteLater();
        app.quit();
});

return app.exec();
}

Output Example (Partial):


Encoded POST data: "name=%E5%BC%A0%E4%B8%89&message=%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81%E8%BF%99%E6%98%AF%E6%B5%8B%E8%AF%95%E4%B8%AD%E6%96%87%E3%80%82"

The server (such as httpbin.org) will be able to correctly parse the original Chinese content.

5. A More Elegant Way: Using <span>QUrlQuery</span>

Qt also provides a higher-level wrapper <span>QUrlQuery</span> that automatically handles encoding, avoiding manual string concatenation:


QUrlQuery query;
query.addQueryItem("name", "张三");
query.addQueryItem("message", "你好,世界!");

QByteArray postData = query.query(QUrl::FullyEncoded).toUtf8();

<span>QUrl::FullyEncoded</span> ensures that all values are correctly encoded. This method is safer and more readable, and is recommended for use in new projects.

Complete example:


QUrlQuery query;
query.addQueryItem("title", "测试标题");
query.addQueryItem("content", "这里是中文内容,包含标点:!@#¥%……&*()");

QNetworkRequest request(QUrl("https://example.com/api/submit"));
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");

QNetworkReply *reply = manager.post(request, query.query(QUrl::FullyEncoded).toUtf8());

6. Common Misconceptions and Precautions

❌ Incorrect Practice 1: Directly concatenating unencoded Chinese


QString postData ="msg=测试"; // The server receives garbled text!

❌ Incorrect Practice 2: Using <span>QString::toPercentEncoding()</span> (default Latin-1)


QString bad ="测试".toPercentEncoding(); // Result is incorrect!

✅ Correct Practice: Always use <span>toUtf8().toPercentEncoding()</span>

🔒 Server-side must also cooperate

Ensure that the server (such as PHP, Node.js, Java, Python Flask/Django) uses UTF-8 to decode the request body. For example:

  • PHP: <span>$_POST['msg']</span> is decoded by default (ensure the page/script is UTF-8);
  • Node.js (Express): Use <span>body-parser</span> and set <span>extended: true</span>;
  • Python Flask: <span>request.form['msg']</span> is automatically decoded to Unicode.

7. Conclusion

Step Action
1 Convert Chinese <span>QString</span> to UTF-8 byte array:<span>.toUtf8()</span>
2 URL encode the byte array:<span>.toPercentEncoding()</span>
3 Concatenate into <span>key=value&...</span> format as POST body
4 Set <span>Content-Type: application/x-www-form-urlencoded</span>
5 The server decodes in UTF-8 to obtain the original Chinese

By following the above methods, the issue of Chinese garbled text in HTTP POST requests in Qt applications can be completely resolved. It is recommended to prioritize using <span>QUrlQuery</span>, as it not only automatically handles encoding but also avoids the security risks associated with manual concatenation (such as unescaped <span>&</span> or <span>=</span> symbols).

Appendix: Recommended Testing Tools You can use https://httpbin.org/post to test your POST requests, as it will return the data you send, making it easy to verify if the encoding is correct.

I hope this article helps you easily tackle Chinese encoding challenges in Qt development!

Others

  1. Domestic Open Source: https://gitee.com/feiyangqingyun
  2. International Open Source: https://github.com/feiyangqingyun
  3. Project Collection: https://qtchina.blog.csdn.net/article/details/97565652
  4. Contact: WeChat feiyangqingyun
  5. Official Store: https://shop114595942.taobao.com/

Leave a Comment