我们每天都在浏览器的地址栏里面很多次输入URL,应该对它非常熟悉。浏览器地址栏包容性很强,英文、中文、日文、韩文统统都能输入,而浏览器也能给出比较正确的反馈。
但是,这只是表象,真正的网络世界对输入语言的要求是非常苛刻的,可以说是专属于英文字符的。
虽然在 URL 中使用一些中文字符从技术上讲不存在识别和传输的问题,但是网络标准协议中却规定了 URL 中只能包含英文字符。
那么,我们在地址栏里看到和使用的中文又是怎么回事呢?
事实上,那只是浏览器的障眼法。虽然我们在浏览器的输入框里使用了中文,可一旦浏览器发出网络请求,请求中的中文将不复存在,会变成我们经常看到却不明所以的东西,比如“%e5%82%bb%e5%91%80”,这就是 URL 中的中文被编码后的结果。
可能大家会觉得这种编码结果有些奇特,跟平时看到的编码比,它多了很多的这个“%”,其实只是分隔符,如果把“%”替换成空格,就可以看到我们熟悉的编码结果了,比如上面的“e5 82 bb e5 91 80”,眼尖的读者可能会看出这就是中文的 UTF-8 的编码。
按照标准进行编码是合理的,但是标准没有规定用什么编码,于是开发人员开始各自为战,有用 UTF-8 编码的,也有用 GB2312 编码的,这两种编码是什么不重要,重要的是两种编码的结果不一样,很多时候后台、前端、终端之间的矛盾就是因它而起的。
更让开发者觉得麻烦的是标准没有提供编码守则,于是程序员开始自由发挥。例如,在 URL 的实际使用过程中,经常会对 URL 的参数进行拼装,拼装的 URL 参数来源往往是没法确定的。
不过,不管参数的内容是什么,为了避免出现中文字符,开发者一般会在 URL 拼装完毕后统一做一次编码。
问题是,参数源可能已经将 URL 编码过一次了,而编码后的字符串是能够再次被编码的,就像俄罗斯套娃一样,所以看到一个编码结果时,开发者甚至没法确定它要被解码多少次才能得到真正的结果。
大家再看到这种包含很多“%”的字符串时,别认为是加密数据,随便找个 URL 解码工具就能还原它。