热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

前端开辟中的字符编码

前端开辟历程当中会打仗林林总总的编码,比较罕见的主如果UTF-8和HTML实体编码,然则web前端的天下却不止这两种编码,而且编码的挑选也会构成肯定的题目,如前后端开辟历程当中差异

前端开辟历程当中会打仗林林总总的编码,比较罕见的主如果 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("\u00E4\u00B8\u00AD\u00E5\u009B\u00BD") // 效果: "中国"

经由过程简朴的 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、

cccc

2、
cccc

3、<&#x69;&#x6d;&#x67;&#x20;&#x73;&#x72;&#x63;&#x3d;&#x31;&#x20;&#x6f;&#x6e;&#x65;&#x72;&#x72;&#x6f;&#x72;&#x3d;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x32;&#x33;&#x29;>
4、

代码中列举了 8 个例子:

  • 第一个在事宜处置惩罚函数 onclick 中输出 HTML 片断;

  • 第二个则输出经实体编码后的 HTML 片断;

  • 第三个则是直接针对 做 16 进制编码;

  • 第四个则是针对 onerror 事宜处置惩罚函数做 16 进制编码;

  • 第五个则是在剧本中输出实体编码的字符;

  • 第六个针对事宜处置惩罚函数做 16 进制编码;

  • 第七个则针对一切的字符做 16 进制编码;

  • 第八个则是在 script 中直接输出 的 unicode 编码

对照效果,前两个例子在点击后都邑弹出 alert;第三个例子则在页面中显现文本 ;第四个例子则会在页面加载早期弹出 alert;第五、七会输出字符串;第六、八则会在第四个例子中的 alert 以后也弹出 alert。如今剖析这些效果,经由过程第一二个例子可晓得,HTML 标签中(除 script 标签)的内联 js 代码能够举行 HTML 实体编码,这是非常重要的一点,我们能够更加明白的举行考证:

cccc

输出的效果天然是 ,这确切论证了我们上文提到的这一点;第三个例子申清楚明了HTML剖析器在举行词法剖析前,起首举行解码,十六进制和十进制皆可,因而,效果天然输出形如 的字符串;第四个例子则紧接着论证了内联在 HTML 的并采纳十六进制编码的 js 代码一样会被准确剖析并实行,这申清楚明了进制编码一样可被 HTML 剖析器剖析;第五、七个例子申明在 js 中一样能够运用实体编码和进制编码,剖析的效果会渲染在页面上;第六个例子则论证了上一看法,只针对事宜处置惩罚函数做进制编码,实行后页面弹出 alert;第八个例子则是在 js 中实行 unicode 编码的字符串,一般 alert。

因而可知,js 代码内联在 HTML 的非 script 标签内,则会恪守 HTML 编码范例:进制编码和实体编码;而在 js 代码(script 标签内以及 js 文件内)中,则顺从 js 编码:1. unicode 情势编码(uxxxx) 2. 一般的 16 进制编码(xH),这可经由过程第八个例子获得证实。之所以在本节提到这么多编码特性,重要提示人人在防备 XSS 时须要注重的几点:

  • 检测用户输入时,不单单议须要提防相似 <> 如许的字符,经由过程 unicode 编码或进制编码仍有能够注入代码

  • 须要针对特定的关键字做过滤,如 eval、write、prototype

  • 尽量制止内联事宜处置惩罚函数的运用

  • js 过滤 src/href/action 属性,如 Javascript:, data:

JS 编码

实在在上节中已提到了 js 编码,即 js 可实行 unicode 编码和十六(八)进制编码后的字符串,然则不支持十进制编码的字串。详细操作可经由过程经常使用的几个函数来完成,如 eval,write,setTimeout,Function 实行编码后的字符串;一样,关于十进制编码的字串,经由过程连系 String.fromCharCodeeval 一样能够实行。

在此附上笔者完成的字符转换,更加天真的完成种种自定义情势的字串编码:

var Code = {};
/**
*
* @param str 待编码字串
* @param jinzhi 进制编码
* @param prefix 前缀
* @param postfix 后缀
* @param count 统共编码的位数,默以为4
* @returns {string}
*/
Code.encode = function({str = '',jinzhi = '16',prefix = '\\u',postfix = ';',count = '4'} = {}){
var ret = '';
var addZero,tmp;
for(let i=0;i tmp = str.charCodeAt(i).toString(jinzhi);
addZero = count - tmp.length + 1;
ret += prefix + new Array(addZero).join('0') + tmp + postfix;
}
return ret;
};
Code.decode = function({str = '',jinzhi = '16',prefix = '\\u',postfix = ';'} = {}){
var ret = '';
var splits = str.split(';');
for(let i=0;i let tmp = splits[i].replace(prefix,'');
ret += String.fromCharCode(parseInt(tmp,jinzhi));
}
return ret;
};
console.log(Code.encode({str: ''}));
console.log(Code.decode({str: Code.encode({str: ''})}))

别的,关于 js 输出点的过滤实在并不仅限于上文提到的如 eval、setTimeout、Function 等几个,因为 JS 语法比较天真相对“破绽”较多,可运用的“线索”也越雄厚,如前段时间在 Stackoverflow 上发明的一个题目,即

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

一样能够实行 JS 代码,确切挺有特性的,详细为何上述情势能够实行代码,请读者本身细致品尝。


推荐阅读
  • PHP图床源码:集成化图床管理系统解决方案
    本项目提供了一套集成化的图床管理系统解决方案,适用于需要高效管理图片资源的场景。系统结构简洁,无需复杂的后台支持。主要文件包括 `huluxia.php`、`index.html`、`inews.php`、`kw.php` 和 `zz.php`,每个文件都承担了特定的功能,确保系统的稳定运行和易用性。 ... [详细]
  • 深入解析JWT的实现与应用
    本文深入探讨了JSON Web Token (JWT) 的实现机制及其应用场景。JWT 是一种基于 RFC 7519 标准的开放性认证协议,用于在各方之间安全地传输信息。文章详细分析了 JWT 的结构、生成和验证过程,并讨论了其在现代 Web 应用中的实际应用案例,为开发者提供了全面的理解和实践指导。 ... [详细]
  • HTML5大文件传输技术深度解析与实践分享
    本文深入探讨了HTML5在Web前端开发中实现大文件上传的技术细节与实践方法。通过实例分析,详细讲解了如何利用HTML5的相关特性高效、稳定地处理大文件传输问题,并提供了可供参考的代码示例和解决方案。此外,文章还讨论了常见的技术挑战及优化策略,旨在帮助开发者更好地理解和应用HTML5大文件上传技术。 ... [详细]
  • 本文深入探讨了层叠样式表(CSS)的核心原理与应用技巧,旨在帮助读者全面理解CSS的工作机制。从选择器、属性到布局模式,文章详细解析了CSS的关键概念,并通过实例展示了如何高效运用这些技术,提升网页设计与开发的水平。 ... [详细]
  • Node.js 教程第五讲:深入解析 EventEmitter(事件监听与发射机制)
    本文将深入探讨 Node.js 中的 EventEmitter 模块,详细介绍其在事件监听与发射机制中的应用。内容涵盖事件驱动的基本概念、如何在 Node.js 中注册和触发自定义事件,以及 EventEmitter 的核心 API 和使用方法。通过本教程,读者将能够全面理解并熟练运用 EventEmitter 进行高效的事件处理。 ... [详细]
  • 本文详细介绍了利用JavaScript实现图片懒加载的有效方法。通过监听窗口的加载和调整事件,可以显著提升网页性能和用户体验。具体实现包括在 `window.onload`、`window.onresize` 和 `window.onscroll` 事件中动态加载图片,确保只有当图片进入可视区域时才进行加载,从而减少初始加载时间并提高页面响应速度。此外,还提供了一些优化技巧,如使用 Intersection Observer API 来进一步简化代码和提升效率。 ... [详细]
  • 如何判断一个度序列能否构成简单图——哈维尔-哈基米算法的应用与解析 ... [详细]
  • 这篇文章将揭示 Vue 和 React 组件库中五个鲜为人知的强大工具。这些工具均以纯 JavaScript 实现,功能卓越。其中,async-validator 是一个数据验证插件,不仅预置了 URL 和电子邮件的验证规则,还支持异步验证功能。 ... [详细]
  • 如何构建并优化微信小程序页面的设计与功能
    本文将深入探讨微信小程序页面的设计与优化方法,旨在帮助开发者高效构建功能完备且用户体验良好的小程序。通过实例分析与技术详解,读者能够掌握从页面布局到功能实现的全过程,提升开发技能与应用质量。 ... [详细]
  • 本文探讨了使用JavaScript实现多种经典排序算法的高效方法,包括冒泡排序、选择排序、插入排序、归并排序和快速排序。为了确保代码的结构清晰和可维护性,我们首先定义了一个 `ArrayList` 类,该类中包含了待排序的数组声明。通过这种方式,我们不仅能够更好地组织代码,还能提高算法的执行效率和可读性。此外,我们还对每种排序算法进行了详细的性能分析和优化建议,以帮助开发者在实际应用中选择最合适的排序方法。 ... [详细]
  • 本文详细介绍了如何在微信小程序中使用JavaScript实现图片上传至PHP服务器的方法。通过具体的代码示例,帮助开发者掌握从客户端选择图片、处理图片数据到服务器端接收并保存图片的完整流程。同时,文章还提供了常见问题的解决方案和优化建议,确保上传过程的高效性和稳定性。 ... [详细]
  • 网站前端开发的核心理念与必备技能解析 ... [详细]
  • 编程心得:精选5.20告白代码,助你赢得佳人芳心,单身人士速来取经!
    编程心得:精选5.20告白代码,助你赢得佳人芳心,单身人士速来取经! ... [详细]
  • IamcurrentlyworkingonasmallphplibrarywhichwouldallowuserstoaccessdatafromtheGoogle ... [详细]
  • 摘要:有些功能还真不能光凭自己的直觉和认识,来自一线的声音才是最真实的用户需求。比方说名片录 ... [详细]
author-avatar
和雅竹
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有