前端工程师的编码遭遇战

导语:由于历史原因,淘宝网的页面编码一直都是gbk,F2E手册中也有明确规范,刚开始的一段时间,F2E们并未遭遇太麻烦的乱码问题,大家相安无事,但随着淘宝的合作方越来越多,合作方的API接口编码可谓五花八门,淘宝的系统和第三方的数据对接之后就暴露出各式各样的乱码问题。有必要再把这个问题缕缕清楚。

我想,可能是在做第一个淘宝网的页面时,工程师只顾写代码,而忘了看一看编辑器的默认编码设置,再后来就将错就错直到今天,如果稍微留神,可能就不会犯下这么一个低级错误。没错,“编码约定”在全站规范中占有及其重要的权重,不幸的是,而这个异常重要的问题却非常容易被忽略,毕竟它不仅仅是“统一页面编码约定”这么简单,甚至包含全站的安全策略(这是显而易见的)。而作为F2E面对各式乱码问题时,更要了解问题的本源,搞清楚能根治问题的方法,而不是依赖于浏览器的某种适应性暂时规避掉乱码,治标不治本。

从二进制码流到显示出字符

众所周知,字符的编码方式有两种惯例,一种是很古老的对ASCII码做某种语言子集的扩展,比如big5和gb2312,分别是繁体字扩展和简体字扩展,两者互不兼容,与之类似的编码还有ISO系列,各个拉丁文的子编码集合也不相互兼容,这种编码的好处是编码集合很小,坏处是不能同时使用多种语言,于是就有了另一种编码惯例:“万国码”,全球所有语言做成一个码表,即unicode码表,显然,这种编码的坏处是码表太庞大,好处是同时使用多种语言。所谓的utf-7、utf-8之类就是unicode的某种相对高效的实现,不管某个字符用utf编码为几个字节,他们都属于同一个unicode超集。我们常遇到的中文编码是gb2312、gbk、gb18030和utf-8,不严谨的讲,前三者大致相互兼容,但都和utf-8不兼容。如果一段文本以gbk(码表)进行编码的话,阅读软件只有按照gbk(码表)解码才能阅读。但机器码显示为最终的字符点阵,阅读软件(浏览器、文本编辑器等)还需要将解码后(通过查找码表将连续的二进制码转换为了字符)的字符码对应到相应的点阵,显然,如果用以显示文本的字体不包含某个字符的点阵,这个字符自然也无法显示出来。更多背景知识可以参照这个ppt。

由于浏览器比较好的兼容性,一般不会出现因为字体问题而出现乱码的情况,但在工程师写代码的时候偶有遇到,比如使用vim以gb2312编码编辑一个文件,当文件中出现“镕”字时,是无法保存这个文件的。这是因为gb2312码表中不存在这个字,但指定gb2312编码的网页是可以显示这个字的,这是因为浏览器通常会采用windows系统编码来解析gb系的页面,通常是gbk。

如果使用editplus或记事本,只需存为ANSI编码就可以,这些编辑器会根据码流去识别到底是gbk还是gb2312还是gb18030的编码,所以 window下很多文本编辑器都没有强行采用某种特定的编码,统一使用系统编码,通常情况下中文win系统中,可以认为ANSI就是gbk。如果使用linux系统,可以参照这里来正确处理你的编辑器的编码。

浏览器如何发送一个带有中文的URL

那么,浏览器打开一个网页,从敲入网址到最终呈现出UI整个过程中,是如何处理编码的呢?整个过程分两个阶段,1,发送URL请求,2,接收数据并呈现。HTTP标准对URL编码有着如是规定(RFC 1738):

“…Only alphanumerics [0-9a-zA-Z], the special characters “$-_.+!*’(),” [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.”
“只有字母和数字[0-9a-zA-Z]、一些特殊符号“$-_.+!*’(),”[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。”

这里不得不提到URL编码,尽管根据RFC的规定,含有中文的URL是非法的URL,但没有规定如何转码,阮一峰的这篇文章详细的介绍了在Firefox和IE中是如何对带有中文的URL进行编码发送HTTP请求的。确切的讲,URL是一种编码“方法”,编码结果依赖于所采用的“码表”,即汉字的内码表示形式。所以,相同汉字有N多种URL编码结果,“淘宝”的utf8编码为“%E6%B7%98%E5%AE%9D”,gbk编码为“%CC%D4%B1%A6”。

这里需要注意的是,一个gb系编码的html页面中的form提交,表单中的中文编码会进行URL编码,但是以gbk格式作转码,utf8页面的form提交,以utf8格式作转码。看这两个例子:

gbk页面的表单提交,utf-8页面的表单提交

这时就需要和后台程序做好约定,页面怎么进行编码,后台逻辑就需要对应的解码。比如淘宝的Search页面和百度搜索页一样,只接收gbk的URL编码。网上这方面的资料也比较多,这里不再赘述。

但如果通过JavaScript的encodeURI(encodeURIComponent亦是同理)做URL编码又会出现什么情况呢?JS只会以utf-8的形式做URL编码,同样参照上面两个例子,不管页面是gbk还是utf-8,JS中的URL编码始终是一样的。这在使用JS库模拟form提交时需要尤为注意,直接提交表单结果正常,用JS库或框架提供的方法模拟拼接查询串提交表单就出问题,也就是这个原因。所以,在用JS拼接查询URL的时候要小心,需要注意后台程序需要的编码是什么格式。

浏览器如何以正确的编码渲染页面

HTTP响应的数据起码有三个地方可以埋藏编码信息:

1,http头中的Content-Type
2,html页面中的meta标签中指定charset
3,页面正文数据(浏览器可以解析正文二进制码来判断编码)

浏览器可以从这三个地方获得HTTP响应报文的编码,此外还有两个因素,浏览器默认编码和操作系统语言类型。

淘宝首页是gbk的编码,HTTP响应头中指定了文档编码为GB2312,同时meta中的charset和页面正文都是gbk编码,浏览器渲染正确。

content-type中的编码设置

源码中的meta标签

如果三者编码不一致,浏览器会首先读取http头中的content-type,若没有设定编码,再查找页面中meta标签中的charset设定,如果还没有就以浏览器默认编码来显示,如果默认编码没有指定,浏览器会通过解析正文内容来判断编码。所以,页面是gbk编码,即便meta属性中设置charset=utf-8,只要content-type中设定为gbk(或者GB2312、GB18030),该页面就正常显示,如果这时没有设定content-type的编码,浏览器就会以meta中的charset属性为准,页面出现乱码。

在PHP中可以这样设置content-type的编码:

header("Content-Type: text/html; charset=GBK");

正确的载入JS文件

html页面载入js文件的时候,需要指定js文件的编码才能正确引用,比如:

<script src="gbk.js" charset="gbk" ></script>

可以参照这个demo

JSONP里的中文处理

根据上面的例子,我们知道载入外部JS文件只要指定charset就可以,对JSONP来讲也是如此,但有一个更彻底的杜绝乱码的方法,将JS文件进行unicode编码,这是因为JS引擎的内码是unicode,所以只要是unicode的文本JS都可以识别。就像这样:

PHP中的json_encode函数可以直接将数组作unicode转码。通过JS也可以进行unicode编码,参照这个Demo。

通过JS获取URL

我们注意到,在使用Firefox打开的地址中包含中文时,将其拷贝粘贴到另外的地方却没有得到中文,而是编码后的URL。这是因为浏览器自作聪明的将URL解码为中文来显示的,当我们需要抓取URL的时候需要特别小心,这个Demo在Firefox和IE下打开,JS得到的URL是不一致的。

Firefox:

开发工程师">

IE:

如果这个页面不和后台数据发生交互,直接通过document.location.href来取URL是ok的,一旦和后台发生交互,则需要非常小心,最常见出问题的场景是带入登录页的回调地址。比如通过这个地址进入淘宝首页:

http://www.taobao.com/?淘宝

在Firefox和IE下都是可以正常访问的,这时点击吊顶中的“登录”,进入登录页,可以看到在Firefox下的回调地址为:

而在IE下的回调地址为:

这时登录淘宝,页面跳转为淘宝首页,可以看到Firefox的地址栏中的URL是正确的,而在IE的地址栏中出现了乱码

Firefox下

IE下

解决办法就是不要用JS去抓取URL写入回调,通过登录页面的Ref或其他方式来抓取。

gbk的页面如何通过JS得到gbk格式的URL编码

我们知道,gbk的页面提交表单是可以作基于gbk的URL编码的,基于这一点,我们可以封装一个函数,实现在gbk页面中使用JS得到gbk格式的URL编码。参照这个Demo,Demo中模拟提交一个表单,然后抓取表单提交的结果,进而得到gbk格式的URL编码。

这样,通过JS就可以控制我希望得到的URL编码了。但在utf-8的页面中是无法实现的。这一点需要尤为注意。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索url
, 浏览器
, 编码
, 阮一峰
, 页面
, utf-8
, gbk
, 前端乱码
, gbk编码
, 前端 js form
, js显示二进制图片
, 国外url编码
, url前端数据
前端, js, form提交
前端工程师、前端工程师育知同创、web前端工程师、前端开发工程师、前端工程师简历,以便于您获取更多的相关知识。

时间: 2024-09-29 06:52:02

前端工程师的编码遭遇战的相关文章

淘宝前端工程师:国内前端行业10日谈

一直想写这篇"十日谈",聊聊我对Web前端开发的体会,顺便解答下周围不少人的困惑和迷惘.我不打算聊太多技术,我想,通过技术的历练,得到的反思应当更重要. 我一直认为自己是"初级"前端开发工程师,一方面我入道尚浅,只有短短几年,另一方面我自知对技术的钻研并不深入,可能是由于环境的原因,当然最重要的是,我幸运的参与到互联网崛起的浪潮之巅.时势造就了一批技能薄弱但备受追捧的"弄潮者",这在很大程度上影响我们对"技术本质"的洞察力,多

5个前端工程师必备的最佳开发工具

 开发工具-前端工程师必备工具"> 原文作者 Arnaud Breton 为前端工程师,特别专注于前端和使用者经验,这篇文章出自于mention blog.以下内容由作者以第一人称撰写. 过去几年一直不断地提到 Web 应用新世代的成长,这些 App 内容变得越来越丰富,带动了前端整体的复杂度大幅增加. 像是 Backbone(藉由提供模型).AngularJS 和 EmberJS 框架都是创造新 App 非常好的框架,增强了所有 Web 的功能;同时,Web 程式语言 Javascrip

淘宝前端工程师:国内WEB前端开发十日谈

中介交易 SEO诊断 淘宝客 云主机 技术大厅 一直想写这篇"十日谈",聊聊我对Web前端开发的体会,顺便解答下周围不少人的困惑和迷惘.我不打算聊太多技术,我想,通过技术的历练,得到的反思应当更重要. 我一直认为自己是"初级"前端开发工程师,一方面我入道尚浅,只有短短几年,另一方面我自知对技术的钻研并不深入,可能是由于环境的原因,当然最重要的是,我幸运的参与到互联网崛起的浪潮之巅.时势造就了一批技能薄弱但备受追捧的"弄潮者",这在很大程度上影响我

js前端工程师和页面构建工程师项目沟通

文章简介:页面构建和js前端不得不说的那点事儿. 作为微博的页面构建工程师,主要职责就是利用html&css,高质量的完成静态页面的制作,保证项目的按时完成.而页面需要的js效果则交给下游的js前端工程师去做.在微博,这两个岗位是分开的.但在大家的思维定势里可能觉得这两个岗位应由一个人来完成最好,毕竟,页面构建工程师写的html结构不一定是js工程师想要的那种,js工程师可能有更高效的方式.所以,在页面构建之前最好能与js工程师沟通一下,把实现方案确定好. 但在实际项目流程中,当进行到页面构建的

成为Web前端工程师的三个阶段

Web 前端工程师每个阶段所需技能大致如下:第一阶段平面设计师 : 良好的美术基础.对色彩有一定深入的理解.富有创意思维.精通PhotoShop.Fireworks 等软件.网页设计师 : (X)HTML.CSS.AS3.精通Flash.DreamWeaver等. 第二阶段UI设计师   : RIA技术,对"3D概念体系"有所认知.这里"3D"即:Design(设计).Development(开发).Deploy(产品部署)等.交互工程师 : JavaScript.

用户体验设计:产品工程师和WEB前端工程师

我敢打赌,在中国,一半以上甚至更多的,以网站为主营业务的或者把网站很看重的公司,没有Web前端工程师和产品工程师这两个职位,甚至有些有点规模的公司也可能没有这个职位,当然,这不能包括像alibaba,sina,163这样的公司,只是指中小型公司而言.如果你们公司有,请给我留言告诉我你们公司的规模和相关的信息. 做得好一点的公司,一般是项目经理/部门主管+投资方(项目管理中的投资方,实际上就是老板,反正就是决定你要做什么并给你钱的人)来承担产品工程师的角色,由美工来承担Web前端工程师的角色,特别

应聘网站前端工程师的简历应该怎么写?

春节前在蓝色理想上发了个"雅虎口碑招聘前端工程师 "的启事, 职位: 前端工程师 薪金: 面议 有效期至: 2009-02-28 工作地点: 浙江杭州西湖区文三西路 公司名称: 雅虎口碑 简历投送邮箱: kaven.yan@yahoo.com 学历: 不限 是否应届: 不限 年龄要求: 不限 性别要求: 不限  职责:负责雅虎口碑网前端的开发 要求:.1.热爱前端,耐住寂寞,并计划长期靠此吃饭2.深刻的理解HTML和CSS,并有丰富的应用经验3.精通JavaScript4.任何有利于前

Web前端工程师定位浅谈

先给前端工程师的工作下个一句话定义:运用前端技术,实现体验的良好传达.如果在前面加上Web,那么是针对Web这个领域的,主要是互联网,也可以将移动通信网络和其他传媒网络(比如IPTV)包含在内,因为其理念是一致的. 现在要在未毕业的学生中找到一个符合技能条件的Web前端工程师可以说是少之又少.而相关领域的从业者,又因为不被重视.干杂活.薪水低等原因,觉得选错了行当,又停止了在这个方向上的努力学习.最终导致企业招不到一位满意的Web前端工程师.这涉及到两个定位的问题,即1)企业如何给Web前端工程

前端工程师新手必读:掌握基本技能弄清概念

公司招了几个刚毕业的学生,作为重构的新手让我来带. 首先感谢感谢党.感谢国家.感谢公司给了我这样的一个机会,对我工作的肯定和认可,让我带这样的一个重构团队,同时我也明白任务的艰巨,但我一定会将工作做好,不负公司对我的期望.(哈哈,好像从小到大,老师都是教育我们要这样先说的.) 在网站的发展史上,初期的网站建设根本不需要网页重构这个职位,WEB1.0时代的网页,只需要程序员,一堆堆的表格嵌套就完成,或者美工进行配合完成,先由美工负责设计好,再用一些自动化的软件拉伸几下,直接将设计好的图就可以通过软