烟消火灭网

宽字符跨域,这名字听着像网络安全术语,其实说的是我们每天都在干的破事——把中文、日文、韩文这些“宽字符”塞进网页、数据库、API接口里,然后发现它们根本不兼容。 上周我调一个电商后台的搜索接口,前端传

宽字符跨域

宽字符跨域,宽字这名字听着像网络安全术语,符跨其实说的宽字是我们每天都在干的破事——把中文、日文、符跨韩文这些“宽字符”塞进网页、宽字数据库、符跨API接口里,宽字然后发现它们根本不兼容。符跨

上周我调一个电商后台的宽字搜索接口,前端传了个“苹果”过来,符跨后端死活查不到数据。宽字抓包一看,符跨前端URL编码后是宽字“%E8%8B%B9%E6%9E%9C”,后端拿到手却变成了“è¹æ”。符跨这玩意儿就是宽字典型的宽字符跨域问题——两边用的字符编码不一样,一个UTF-8,一个GBK,中间没做转换,直接硬怼。

这事儿在跨国业务里尤其恶心。我们公司有个日本客户,他们的商品名称全是片假名,存数据库时用的SJIS编码。结果我们这边系统升级,统一改成UTF-8,老数据全乱了。客户后台一看,商品名成了“オンライン”,直接懵了。后来没办法,写了个脚本把SJIS字段逐条转码,转完还得人工抽查,生怕哪个字符映射错了。

别以为只有后端才碰这问题。前端表单提交,用户输入emoji,那玩意儿是四字节的UTF-8,但很多老系统数据库只支持三字节的utf8mb3,一提交就报错。去年我做个留言板,用户发了个😊,结果整个页面白屏——数据库字段长度不够,直接抛异常。最后改成utf8mb4,字段类型从varchar(255)扩到varchar(512),才算消停。

跨域这词儿其实也有字面意思。浏览器里,不同域的页面之间传值,默认是拦着的,但宽字符往往能绕过限制。比如你用JSONP跨域取数据,返回的JSON里带中文,如果对方服务器没设Content-Type为application/json; charset=utf-8,浏览器就会按ISO-8859-1解析,中文全变乱码。这时候你得手动decodeURIComponent,或者干脆用fetch加mode: 'cors',让浏览器自己处理编码。

最坑的是那些老掉牙的第三方接口。前阵子对接一个物流查询API,文档里写着“支持GBK编码”,我寻思着现在谁还用GBK,结果真就返回GBK的XML。我用axios默认UTF-8去解析,标签属性全乱。后来用iconv-lite把response.data转成Buffer再decode,才拿到正确的运单状态。

说实在的,宽字符跨域这问题,根子在于历史包袱。ASCII时代没人想过中文要占两个字节,后来各国搞自己的编码,再后来国际标准化组织搞了个Unicode,但老系统改不动。现在前端框架都默认UTF-8了,可后端还有一堆跑在Windows Server上的老代码,用着本地化编码。你没法指望所有系统一夜之间统一,只能靠中间层做适配。

我的建议是,新项目一律UTF-8,数据库字段用utf8mb4,API响应头显式声明charset,前端提交前统一encodeURIComponent。遇到老接口,别硬刚,写个适配器,转码、解码、容错,全包进去。别嫌麻烦,这活儿干多了,你自然就懂什么叫“字符面前,人人平等”——不平等,就自己动手抹平它。

访客,请您发表评论:

© 2026. sitemap