URL编码“陷阱”
作者:LuLi 来源:SimpleLife 发布时间:2008-03-04 16:57:00
上次谈到客户端和服务端的编码“陷阱”,其中对url编码只是提及带过,并没有做深入讨论,事实上由于浏览器环境的复杂和不一致性,我们也很容易掉进url编码“陷阱”。首先看一个demo,我的测试是在FF和IE6上进行的。
在FF下表现正常,而在IE6下当点击第一个链接的时候,服务端给我们返回的id变量值竟然出现了怪异,和我们传递过去的“实验室”不一致,这看起来似乎很怪异。整个过程中我对get过来的参数id除了做输出,没有做任何额外处理,上面的怪异现象实际上是浏览器造成的。
一、URL编码需要指定被编码字符的字符集
首先我们要明确的是在对ASCII码以外的字符做URL编码时,你要清楚的知道被编码的字符的字符集,这点很重要。例如我们要对“汉字”这两个字符做URL编码,你可能得到的是“%E6%B1%89%E5%AD%97”,也可能是“%BA%BA%D7%D6”。为何会有两个了?事实上还有更多。前者是UTF8下“汉字”的URL编码,后者是GB2312下“汉字”的URL编码。如果客户端是针对字符集A做的URL编码,而服务端默认是以字符集B处理,那显然就掉进陷阱了。(PS:随后有一个测试可以看到)
1、页面中的字符编码
当服务端将页面代码发送给客户端并显示在浏览器里时,该页面中的字符编码就已经确定了,它可能是服务端在header中直接指定的,也可能是在页面的meta信息中设置了charset,具体见客户端和服务端的编码“陷阱”中的第一和第二点分析。以上面那个怪异的demo为例,页面的字符集是utf-8,当点击第一个“实验室”链接时,IE6地址栏是“http://www.v-sky.com/demo/urlencode.php?id=实验室”,而FF下是“http://www.v-sky.com/demo/urlencode.php?id=%E5%AE%9E%E9%AA%8C%E5%AE%A4”,对比可知,对于链接中的非ASCII码IE是“不会”做处理的(PS:事实上IE的编码过程是在背后进行的,没有在地址栏展现给浏览者而已),而FF会根据字符本身的字符集做URL编码(PS:你可以将此页面字符集设置为GB2312以后测试,FF下的地址栏会变成GB2312对应的URL编码)
2、URL地址栏中的字符编码
同样在针对上面的怪异demo,刚才我们都是通过点击链接请求一个新的URL来传递参数,现在我们直接在地址栏中给id输入参数“实验室”,然后回车察看结果。你会发现无论是IE还是FF,服务端输出的变量都是乱码,在FF的地址栏中我们可以看到这里是针对GB2312字符集的“实验室”做的URL编码,而服务端是以UTF8编码处理的,这就造成了输出乱码,前面提到的陷阱出现了。
简单来说就是浏览器中输入字符的编码是根据浏览器和用户在浏览器上的个人设置来确定的,这里有一个详细的说明,我没有对各种情况都做测试,因为首先我不会用非ASCII码命名文件,其次非ASCII码的传参随后有更好的解决方案。
二、对ASCII码以外的特殊字符统一编码
实际项目中很少会出现包含非ASCII码的链接,能够避免这种情况最好,尤其是希望用户容易访问的地址更应当考虑易用性。但如果你真的因为某些原因无法避免,那么你只有主动对这些特殊URL进行统一的URL编码,避免IE这样的浏览器来捣乱,就跟demo中的第二个链接的做法一样。
对于接受用户输入而构造出来的URL请求,例如搜索引擎入口,至少会GET传递一个关键字参数。如果对你的项目而言这是一个很重要的功能,那么你可能需要将各种情况都考虑进来,这个功能www.google.cn考虑的就很不错,页面编码本身是utf-8的,如果从搜索框搜索的,那么URL中是针对UTF8的关键字做的URL编码,如果是用户从地址栏输入,也就是针对GB2312的字符集做的URL编码,这里google在服务端应该是做了字符编码的判断,同样能够准确得到搜索结果,可用性不错,嘿嘿。
(PS:这里我自己也有一个疑问,目前没有找到直接的资料说明。对于包含非ASCII码的链接,IE会在背后做编码处理,只是没有像FF那样直接在地址栏反应出来,这点在HTTP通信中有资料说明。针对上面的demo,我尝试将“实验室”更换为其他字符测试,例如“你好”、“奥运”等,IE下并为出现demo中的怪异情况,这就说明PHP在接收GET过来的参数时,对于ASCII码以外的某些特殊字符并没有正确接收,问题是出在哪儿了?如果哪位知道原因希望告知。)


猜你喜欢
- 一、查看實例名時可用1、服务—SQL Server(实例名),默认实例为(MSSQLSERVER)或在连接企业管理时-查看本地实例2、通過注
- 一、类的构造函数与析构函数_init__ 函数是python 类的构造函数,在创建一个类对象的时候,就会自动调用该函数;可以用来在创建对象的
- qqbot 是一个用 python 实现的、基于腾讯 SmartQQ 协议的 QQ 机器人框架,可运行在 Linux 、 Windows 和
- 最近网上流行着一些采集程序,更多人拿着这些东西在网上叫卖,很多不太懂的人看着那些程序眼羡,其实如果你懂一些ASP,了解自动采集程序的原理后,
- 基本使用首先要下载 pymysqlpip install pymsql以下是 pymysql 的基本使用import pymysql# 链接
- 本文实例讲述了php简单定时执行任务的实现方法。分享给大家供大家参考。具体实现方法如下:<?phpignore_user_abort(
- 1.创建一个项目django-admin.py startproject HelloWorld2.进入HelloWorld项目,在manag
- Get方法在超链接后边紧跟要传递的参数对于用户是可见的如:http://tieba.baidu.com/f?kw=%D6%A3%D6%DD%
- python数值与字符串高级用法1.概述这篇是一篇没有尽头的文章,每当过段时间,再次打开就会看到不一样的内容,有新东西在更新啊。是啊,之所以
- 首先感谢朋友们对第一篇文章的鼎力支持,感动中....... 今天说的是选择排序,包括“直接选择排序”和“堆排序”。话说
- Conditional-CSS允许你针对单一浏览器或浏览器组写出有逻辑条件的可维护的特定的CSS声明。使CSS针对特定的浏览器。简化你对CS
- [mail function] ; For Win32 only. SMTP = mail3.focuschina.com smtp_por
- 1.首先需要安装pandas, 安装的时候可能由依赖的包需要安装,根据运行时候的提示,缺少哪个库,就pip 安装哪个库。2.示例代码impo
- 一、query传参编程式导航 使用router.push 或者 router.replace 的时候,改为对象形式新增query 必须传入一
- 本文实例讲述了php实现的三个常用加密解密功能函数。分享给大家供大家参考,具体如下:算法一://加密函数function lock_url(
- 1、pyqtgraph库数据可视化效果还不错,特别是窗体程序中图像交互性较好;安装也很方便,用 pip 安装。2、在Python中新建一个
- 前言在没有深度使用函数回调的经验的时候,去看这些内容还是有一点吃力的。由于Node.js独特的异步特性,才出现了“回调地狱”的问题,这篇文章
- 从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例?有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,
- 已经11月了,不知道还有没有人看华强买瓜。。。要把华强卖瓜做成字符视频,总共分为三步读取视频把每一帧转为字符画把字符画表现出来 读
- 首先:我们介绍一下socket什么是socket:1. socket 在操作系统中它是处于应用层与传输层的抽象层,它是一组操作起来非常简单的