资讯专栏INFORMATION COLUMN

前端开发中的字符编码

Rindia / 730人阅读

摘要:当然,也可自己写一个转换函数,按照一定规则便行为编码的字节,如下例中国结果中国结果结果通过简单的函数,就可以完成编码到编码的转换,进而完成宽字节字符到编码的转换。

前端开发过程中会接触各种各样的编码,比较常见的主要是 UTF-8 和 HTML 实体编码,但是 web 前端的世界却不止这两种编码,而且编码的选择也会造成一定的问题,如前后端开发过程中不同编码的兼容、多字节编码可能会造成的 XSS 漏洞等。因此,本文旨在更好的全面了解涉及前端开发领域的字符编码,避免可能出现的交互和开发中的忽视的漏洞。

URL 编码

我曾经在 URL 编码解码和 base64 一文中讲述了 URL 编码中的三组函数,并对比了这三组函数与 base64 编码的关系,在此简要说明一下。

escape/unescape 函数针对宽字符做 unicode 编码,并针对码值做十六进制编码,所以使用 escape 针对汉字编码会得到形如 uxxxx 的结果;encodeURI/decodeURI, encodeURIComponent/decodeURIComponent 函数针对宽字节编码却不同于 escape,首先针对宽字节字符进行 UTF-8 编码,然后针对编码后的结果进行 替换,得到结果。以上所述都是针对宽字节而言,对于编码靠前的 ASCII 字符而言,上述三组函数的安全字符的范围也有所不同,具体可在上文中了解。

base64 编码

base64 编码在前端通常用于图片和 icon 的编码,它将每 3 个 8 位字节为一组,分成 4 组 6 位字节,并且每个字节的高位补零,形成 4 个 8 位的字节,由此可看出 base64 编码是可逆推的。在大多数浏览器中,提供了 ASCII 字符的 base64 编码函数,即 window.btoa()。该函数无法针对宽字节进行base64编码,若针对中文编码,则需现转换位 UTF-8 编码,然后进行 base64 编码。

function unicodeToBase64(s){
    return window.btoa(unescape(encodeURIComponent(s)))
  }

通过 encodeURIComponent 对宽字节字符编码,是 %xx 形式的编码,与 UTF-8 编码的区别仅在于前缀(这是由规范 RFC3986 决定的,将非 ASC 字符进行某种形式编码,并转换为 16 进制,并在字节前加上“%”)。因此通过 unescape(encodeURIComponent(s)) 可以转化为 UTF-8 字节。当然,也可自己写一个转换函数,按照一定规则便行为 UTF-8 编码的字节,如下例:

unescape(encodeURIComponent("中国")) //结果:"中国"
encodeURIComponent("中国") //结果:"%E4%B8%AD%E5%9B%BD"
console.log("u00E4u00B8u00ADu00E5u009Bu00BD") // 结果: "中国"

通过简单的 replace 函数,就可以完成 URL 编码到 UTF-8 编码的转换,进而完成宽字节字符到base64编码的转换。有了这个函数,我们手动生成一些 data URI 形式的内容,只需制定 MIME 类型和编码方式,就可以实现文本的转换,如以下代码:

abc
// 未编码前:test
前端 UTF-8 编码与后端 GBK 编码的兼容

目前前端大都采用 UTF-8 进行编码,不管是 html、js 抑或是 css,而后端则由于历史原因大都采用 GBK 或 GB2312 进行解码,因此前端通过 parameter 传递的 URL 编码的字符串就不可能直接在后台进行解码,为了更好的兼容性,前端可进行两次 URL 编码,即 encodeURIComponent(encodeURIComponent(“中国”)),这样后端接收到参数后,先使用 GBK 或 GB2312 解码,得到了 UTF-8 编码后再使用 UTF-8 解码即可。两次编码主要是利用“ASC 字符使用 GBK 或 GB2312 编码不变”的特点完成,富有技巧。

HTML 实体编码与进制编码

实体编码针对HTML的预留字符而言,如 <> 等。实体编码有两种形式 &实体名;&entity_number;,由于浏览器对 &实体名; 的兼容性有差别,因此最好采用实体号的形式编码。

进制编码,顾名思义将ASC字符对应的码值按照十六进制或十进制编码,并转化为 &#x;(16进制)&#D;(10进制) 形式。

单单针对实体编码而言并没有什么特殊强调的点,之所以把它多带带列为一个章节,意在强调这两种编码与 js 代码的作用域的关系。

1、

另外,对于 js 输出点的过滤其实并不仅限于上文提到的如 eval、setTimeout、Function 等几个,由于 JS 语法比较灵活相对“漏洞”较多,可使用的“线索”也越丰富,如前段时间在 Stackoverflow 上发现的一个问题,即

(0)["constructor"]["constructor"]("return "abc;"")()

同样可以执行 JS 代码,确实挺有特点的,具体为什么上述形式可以执行代码,请读者自己仔细品味。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79395.html

相关文章

  • BASE64编码乱码问题的浅层分析与解释

    摘要:当后端将数据取出再传给前端时,发生了编码混乱的问题。这样的编码错误问题导致数据上的,会造成不良的用户体验。但是,不幸的是,各方对该编码的规则是不同的,这也造成乱码的隐患。 本文由作者朱臻授权网易云社区发布。 1问题案例 曾在开发过程中,我们遇到了BASE64编码乱码的问题,该问题的场景如下: 当web前端,将带有中文字符的字符串base64编码后,传到后端。当后端将数据取出再传给we...

    yacheng 评论0 收藏0
  • 前端字符编码小结

    摘要:导语本文源于微信游戏春节王者摇心愿活动英雄语音祝福自定义输入模块开发过程,对踩过的前端字符编码的坑进行记录总结。只规定了字符编码,而并没有规定具体的编码方式。 导语 本文源于微信游戏春节王者摇心愿活动英雄语音祝福自定义输入模块开发过程,对踩过的前端字符编码的坑进行记录总结。 Unicode 字符 Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它...

    gitmilk 评论0 收藏0
  • web前端开发编码规范及性能优化

    摘要:性能优化页面渲染减少页面修改元素多个样式可以通过修改完成这样可以把多次减少为一次修改元素多个样式可以分为三步先隐藏再修改最后显示。 代码优化 这个部分仅仅将代码优化本身,不考虑性能,关于代码部分的性能优化在 页面渲染 部分 代码优化 中 HTML+CSS 符合 XHTML 规范: 小写,正确嵌套,必须关闭; 双引号,合理缩进,utf-8编码; 标签语义化,便于维护; 合理注释,比如 ...

    zhaofeihao 评论0 收藏0
  • web前端开发编码规范及性能优化

    摘要:性能优化页面渲染减少页面修改元素多个样式可以通过修改完成这样可以把多次减少为一次修改元素多个样式可以分为三步先隐藏再修改最后显示。 代码优化 这个部分仅仅将代码优化本身,不考虑性能,关于代码部分的性能优化在 页面渲染 部分 代码优化 中 HTML+CSS 符合 XHTML 规范: 小写,正确嵌套,必须关闭; 双引号,合理缩进,utf-8编码; 标签语义化,便于维护; 合理注释,比如 ...

    zsy888 评论0 收藏0

发表评论

0条评论

Rindia

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<