|
|
VC++实现的URL编码urlencode的两个版本(ansi和UTF-8)
- // 简单 URL 编码(UTF-8 下更严谨应先转 UTF-8,这里按 ANSI 示例)
- CString UrlEncode_Ai(const CString& src)
- {
- CStringA sA(src); // 若是 Unicode,则转为 ANSI;需要 UTF-8 可改用 WideCharToMultiByte
- CStringA out;
- for (int i = 0; i < sA.GetLength(); ++i) {
- unsigned char c = (unsigned char)sA[i];
- if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
- out += c;
- }
- else if (c == ' ') {
- out += '+';
- }
- else {
- char buf[4];
- _snprintf_s(buf, _TRUNCATE, "%%%02X", c);
- out += buf;
- }
- }
- #ifdef _UNICODE
- return CString(out);
- #else
- return out;
- #endif
- }优化下这个函数。。中文会乱码,服务端为springboot的。这是MFC下UNICODE编码下使用的。
复制代码- // UTF-8 表单用的 URL 编码(适用于 Unicode/MBCS,服务端 Spring Boot 默认 UTF-8)
- CString UrlEncode_Ai(const CString& src)
- {
- // 1. 先把 CString (UTF-16) 转成 UTF-8 字节串
- int utf8Len = WideCharToMultiByte(
- CP_UTF8, // 目标编码 UTF-8
- 0,
- src,
- -1, // 以 '\0' 结束
- NULL,
- 0,
- NULL,
- NULL
- );
- if (utf8Len <= 1) {
- return _T("");
- }
- CStringA utf8Str;
- LPSTR pBuf = utf8Str.GetBuffer(utf8Len);
- WideCharToMultiByte(
- CP_UTF8,
- 0,
- src,
- -1,
- pBuf,
- utf8Len,
- NULL,
- NULL
- );
- utf8Str.ReleaseBuffer();
- // 2. 对 UTF-8 字节做 URL 编码
- CStringA out;
- for (int i = 0; i < utf8Str.GetLength(); ++i) {
- unsigned char c = (unsigned char)utf8Str[i];
- if ((c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') ||
- (c >= '0' && c <= '9') ||
- c == '-' || c == '_' || c == '.' || c == '~')
- {
- out += c;
- }
- else if (c == ' ')
- {
- out += '+';
- }
- else
- {
- char buf[4];
- _snprintf_s(buf, _TRUNCATE, "%%%02X", c);
- out += buf;
- }
- }
- #ifdef _UNICODE
- return CString(out); // 从 UTF-8 编码后的 ASCII/HEX 文本转回 CString(只是容器,不再做字符集转换)
- #else
- return out;
- #endif
- }
复制代码要点说明: - 使用 WideCharToMultiByte(CP_UTF8, ...) 显式把 CString(内部 UTF‑16)转为 UTF‑8 字节流。
- URL 编码遍历的是 UTF‑8 字节,每个中文会变成 3 个字节,然后分别 %E4%B8%AD 这种形式。
- Spring Boot 默认按 UTF‑8 解码 application/x-www-form-urlencoded,两边就对得上了,不会再出现中文乱码问题。
- 函数返回的 CString 只是装一串 ASCII 字符(a-zA-Z0-9%+ 等),不会受项目字符集设置影响。
- CString phone = UrlEncode_Ai(_T("13812345678"));
- CString content = UrlEncode_Ai(_T("登录验证码:中文测试"));
- CString form;
- form.Format(_T("phone=%s&content=%s"), phone, content);
复制代码 再配上 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 就可以和 Spring Boot 正常对接了。 |
|