C#向WinForm内嵌WebBrowser控件传递UTF-16日文字符串报错问题
针对WinForm WebBrowser日文JSON传递无效字符问题的解决方案
现有问题分析
当前C#端通过Encoding.Unicode(UTF-16LE)转Base64传递JSON,JS端手动拼接双字节转字符串的逻辑存在缺陷:未处理UTF-16代理对(4字节字符),且IE环境下手动编码解码容易触发不可见控制字符、转义不完整等问题,最终导致JSON.parse抛出无效字符错误。
以下是针对性解决方法:
方案1:修正JS端UTF-16LE解码逻辑,兼容代理对
改用IE原生ActiveX对象处理二进制解码,避免手动拼接字符的错误:
function dispatcher(message) { // 用ADODB.Stream处理UTF-16LE解码 var stream = new ActiveXObject("ADODB.Stream"); stream.Type = 1; // 二进制模式 stream.Open(); // Base64转二进制(兼容IE的实现) var doc = new ActiveXObject("MSXML2.DOMDocument.3.0"); var elem = doc.createElement("tmp"); elem.dataType = "bin.base64"; elem.text = message; stream.Write(elem.nodeTypedValue); stream.Position = 0; stream.Type = 2; // 文本模式 stream.Charset = "UTF-16LE"; // 匹配C#端的Encoding.Unicode var decodedString = stream.ReadText(); stream.Close(); try { var jsonObj = JSON.parse(decodedString); // 后续业务逻辑 } catch (e) { console.error("JSON解析错误: ", e.message); // 输出解码字符串排查问题 console.log("解码后内容: ", decodedString); } }
C#端代码无需修改。
方案2:切换为UTF-8编码,简化解码逻辑
UTF-8在IE JS环境中兼容性更好,无需处理代理对:
C#端修改编码方式
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(msg); var msgB64 = System.Convert.ToBase64String(plainTextBytes); if (!string.IsNullOrEmpty(msgB64)) { object[] init_args = { msgB64 }; mForm.GetWebBrowser().Document.InvokeScript("dispatcher", init_args); }
JS端解码逻辑
function dispatcher(message) { // Base64解码后转UTF-8字符串(兼容IE的写法) var decodedBytes = window.atob(message); // IE10+支持,低版本可保留原Base64库 var utf8Str = decodeURIComponent(escape(decodedBytes)); try { var jsonObj = JSON.parse(utf8Str); // 后续业务逻辑 } catch (e) { console.error("JSON解析错误: ", e.message); console.log("解码后内容: ", utf8Str); } }
方案3:提前过滤JSON中的控制字符
部分无效字符来自JSON中的不可见控制字符(如U+0000-U+001F),C#端序列化后先清理:
using System.Text.RegularExpressions; // 假设msg是已序列化的JSON字符串 var cleanedJson = Regex.Replace(msg, @"[\x00-\x1F\x7F]", match => { // 将控制字符转为JSON标准转义序列 char c = match.Value[0]; return $"\\u{(int)c:X4}"; }); // 后续Base64编码逻辑不变 var plainTextBytes = System.Text.Encoding.Unicode.GetBytes(cleanedJson); var msgB64 = System.Convert.ToBase64String(plainTextBytes);
辅助排查步骤
- 在JS的
catch块中输出解码后的字符串,定位具体触发错误的字符; - 用本地文本编辑器打开C#端的JSON字符串,检查是否存在未转义的特殊符号。
内容的提问来源于stack exchange,提问作者Dana Root
相关产品推荐
相关产品推荐

