前端编码那些事

前端开发中编码的问题一向是让人头疼的,尤其是在以gbk为基础页面编码的淘宝,情况更加复杂,除了常见的页面文件的编码之外,对不同编码js/css文件的引用、meta的charset设置、表单提交的URL编码等问题的处理稍微粗心就会出问题,特别是ajax中的编码转换,始终缺乏统一方便的解决方案,今天我们就分享两个js转码的常见案例的解决。首先,我们应当了解编码相关的一些基本概念:

  • gbk和utf-8是不兼容的两种编码,unicode是万国码码表的简称
  • utf-8编码是unicode的一种实现
  • js引擎的内码是unicode
  • URL编码是将字符裸码以16进制显示出来,每个字之前冠以“%”
  • 因此,URL编码的结果只唯一和字符当前存储的裸码有关,原则上转换过程不查任何码表
  • unicode码表中,中文字符的范围为4E00到9FA5
  • js所识别的unicode表示形式为“\uXXYY”
  • js中的encodeURI是对字符串进行URL编码,编码基于utf-8的裸码
  • js中的escape是对字符串进行unicode转码,转码基于unicode码表
  • form表单提交会对参数进行URL编码,编码所基于的裸码类型和页面编码有关

基于以上知识点,可以初步得出:

  • js无法直接进行基于gbk裸码的url编码
  • js无法直接进行转换为’\uXXYY’形式的unicode编码

而在ajax过程中,通过js传参经常会遇到需要gbk url编码和直接传输unicode编码的情况,尤其当通过json传数据的时候。在php中,对一个对象进行json_encode转换的时候,会自动将中文转换为unicode,这里的unicode可以直接被js识别,因此在js中是只要将json串转换为对象即可,不用解码,php代码为:

$a = array(‘a’=>11,’b'=>’淘宝’);//json
echo json_encode($a);//输出 {“a”:11,”b”:”\u6dd8\u5b9d”}

而php中进行url编码默认是以utf8的方式

//输出 %E6%B7%98%E5%AE%9D ,这里是utf8方式的URL编码
echo urlencode(‘淘宝’);

如果想进行gbk方式的URL编码,则可以

$s = ‘淘宝’;
$g = iconv(‘utf-8′, ‘gbk’,$s);//utf8字符串转换为gbk字符串
echo urlencode($g);//输出 %CC%D4%B1%A6 ,这里是gbk方式的URL编码

php中对URL编码的解码是上面的逆操作

//gbk URL解码:输出 淘宝
echo urldecode(‘%CC%D4%B1%A6′);
//utf8 URL解码:输出 淘宝
echo iconv(‘utf-8′,’gbk’,urldecode(‘%E6%B7%98%E5%AE%9D’));

这里,我们用模拟表单提交的方法来实现js中的gbk URL编码,因为,gbk编码的页面的form表单提交的URL编码是和页面编码一致的,我们模拟表单提交给一个隐藏的iframe,然后取得iframe的src中的提交结果,就得到了gbk URL编码

gbk URL编码的demo。

而如果要在js中模拟php中的json_encode只对中文进行unicode编码,则需要遍历字符串,用escape作转换,然后替换没用的字符

//js中只对中文进行unicode编码
var foo = function(s){
    return s.replace(/[\u4E00-\u9FA5]/ig,function(w){
        return escape(w).toLowerCase().replace(/%/ig,’\\’);
    });
};

若对所有字符进行unicode编码,则直接escape就可以了

以上来自:http://jayli.github.io/blog/data/2010/12/13/encode.html

最近项目制作中关于编码的两个收获:

  1. 使用js ajax获取代码时,所传递的地址内容必须是UTF-8格式(js无法直接进行基于gbk裸码的url编码),否则会出现乱码(不知道是否可以在获取内容后转换)?
  2. 使用cookie设置时,如果变量为中文,需要将内容转换为Unicode格式,获取cookie时再转换回来,如下:
function isetCookie(n, v) {
	    document.cookie = n + "=" + escape(v) + "; path=/; domain=" + window.location.hostname.replace(/\w+((\.\w+)+)/, "$1") + "; expires=" + new Date().toGMTString().replace(/\d\d:\d\d:\d\d GMT|UTC$/, "23:59:59");
	}
	function igetCookie(n) {
	    //取cookies函数
	    return unescape(unescape(document.cookie.replace(new RegExp(".*(?:^|; )" + n + "=([^;]*).*|.*"), "$1")));
	}
	function delCookie(n) {
	    document.cookie = n + "=; path=/; domain=" + window.location.hostname.replace(/\w+((\.\w+)+)/, "$1") + "; expires=" + new Date().toGMTString().replace(/\d\d:\d\d:\d\d GMT|UTC$/, "23:59:59");
	}

设置:isetCookie(‘city’,’广州’);

获取:igetCookie(‘city’);


关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流