zoukankan      html  css  js  c++  java
  • URL编码

    URL的特性

    可移植性

      URL需要通过各种不同的协议来传送,那么组成URL的字符就要求被所有网络协议所识别,只能使用通用的安全字母表中的字符。

      URL字符使用的是US-ASCII 字符集,也叫做标准7位ASCII

    可阅读性

      US-ASCII中有些字符虽然是可移植的,但因为不可见、不可打印,无法阅读,所以也不能在 URL 中使用。7位ASCII共有128个字符,其中33个不可打印字符,95个为可打印字符

    完整性

      URL 中包含除通用的安全字符以外,有时候还希望包含一些非安全字符,比如汉字。这就需要我们对这些非安全字符进行编码。编码成ASCII码中安全的字符。

    另外,ASCII码95个可打印字符中有些在URL中被用于特殊用途或者留待将来用于特殊用途。这些特殊字符往往用来分隔URI组件或者子组件的分隔符。

      Url可以划分成若干个组件,协议、主机、路径等。

      有一些字符(:/?#[]@)是用作分隔不同组件的。例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数,等等。

      还有一些字符(!$&'()*+,;=)用于在每个组件中起到分隔作用的,如=用于表示查询参数中的键值对,&符号用于分隔查询多个键值对。

      服务器端在解析URL时,就是使用这些具有特殊意义的分割符将URL解析成各个组件(协议,主机,路径,参数字符串)或者子组件(参数字符串中的键和值)

      但这些特殊字符用于特殊用途之外时,就会造成歧义,也需要进行编码。比如=用于分割键和值时(如a=eee),不需要进行编码,但如果=作为字符串值中的一个字符时(如a=ee=e, ee=e为一个字符串值),就必须要编码

    总结:组成URL的字符只能是7位ASCII码中的95个可打印字符。

              当URL中包含有95个可打印字符以外的字符时,则必须对这些字符进行编码

         当95个可打印字符中的特殊字符被用于特殊用途时,不能被编码,但如果被用于非特殊用途时也必须要进行编码,如上面=的用途。

              当95个可打印字符中没有特殊意义的安全字符,可以编码,也可以不编码

    URL中的特殊字符(保留及受限字符)

    URL的编码机制

    URL的编码机制非常简单。

    一个字符在字符集中的编码值就是一个数字。这个数字可能由一个或多个字节组成。

    URL编码就是在这个字符对应的编码值的每个字节前加上%,并且用16进制来表示。

    比如如果要编码a,a在ASCII字符集中的编码值为97(10进制),ASCII字符集都是单字节字符,那么二进制表示就是 0110 0001,十六进制表示就是61,所以进行编码后就是%61

    即使是同一个字符,在不同的字符集中可能具有不同的编码值,而且可能由不同数目的字节组成。所以使用不同的字符集对字符进行的编码也不相同。

    比如 "春" 字,在utf-8中的编码值为 "E6 98 A5" ,由3个字节组成,URL编码后就是"%E6%98%A5"。

    而在GB2312中,"春" 字的编码值为"B4 BA", 所以URL编码后就是"%B4%BA"

    由于历史的原因,有一些Url编码实现并不完全遵循这样的机制

    URL的编码的现状

    网络标准RFC 1738对URL的字符组成做了硬性规定,没有规定具体的编码方法和编码字符集,而是交给应用程序(浏览器)自己决定。这导致"URL编码"成为了一个混乱的领域。

    前辈们的关于浏览器的默认URL编码的结论如下。随着浏览器版本的更新以下结论可能并不适应,仅供参考,了解下现状。

    结论1就是,网址路径的编码,用的是utf-8编码。 (测试方法:浏览器中直接输入网址)

    结论2就是,查询字符串的编码,用的是操作系统的默认编码。(测试方法:浏览器中直接输入网址)

    结论3就是,GET和POST方法的编码,用的是网页的编码。(测试方法:在已打开的网页上,直接用Get或Post方法发出HTTP请求)

      这时的编码方法由网页的编码决定,也就是由HTML源码中字符集的设定决定。

      <meta http-equiv="Content-Type" content="text/html;charset=xxxx">

    结论4就是,在Ajax调用中,IE总是采用操作系统的默认编码,而Firefox总是采用utf-8编码。(测试方法:由Javascript生成HTTP请求,也就是Ajax调用)

    由此可见,应用程序自己进行URL编码时,在服务器端无法判断使用了那种字符集进行的编码,所以在解码时就可能使用了错误的字符集进行解码,从而造成乱码。

    解决这种问题的方法就是手动对URL用已知的字符集进行编码,不给应用程序插手的机会。如使用javaxcript中的encodeURI和encodeURIComponent等进行编码。

    Javascript中的escape, encodeURI和encodeURIComponent的区别

    安全字符不同:

    • escape(69个):*/@+-._0-9a-zA-Z
    • encodeURI(82个):!#$&'()*+,/:;=?@-._~0-9a-zA-Z
    • encodeURIComponent(71个):!'()*-._~0-9a-zA-Z

      encodeURI比encodeURIComponent多了11个安全字符  # $ & + , / : ; = ? @

    对Unicode字符的编码方式不同:

      对于ASCII字符,这三个函数的编码方式相同,均是使用百分号+两位十六进制字符来表示。

      对于Unicode字符,escape的编码方式是%uxxxx,其中的xxxx是用来表示unicode字符的4位十六进制字符。这种方式已经被W3C废弃了。但是在ECMA-262标准中仍然保留着escape的这种编码语法。encodeURI和encodeURIComponent则使用UTF-8对非ASCII字符进行编码,然后再进行百分号编码。这是RFC推荐的。因此建议尽可能的使用这两个函数替代escape进行编码。

    适用场合不同:

      encodeURI被用作对一个完整的URI进行编码,而encodeURIComponent被用作对URI的一个组件进行编码。

      从上面提到的安全字符范围表格来看,我们会发现,encodeURIComponent编码的字符范围要比encodeURI的大。我们上面提到过,保留字符一般是用来分隔URI组件(一个URI可以被切割成多个组件,参考预备知识一节)或者子组件(如URI中查询参数的分隔符),如:号用于分隔scheme和主机,?号用于分隔主机和路径。由于encodeURI操纵的对象是一个完整的的URI,这些字符在URI中本来就有特殊用途,因此这些保留字符不会被encodeURI编码,否则意义就变了。

      组件内部有自己的数据表示格式,但是这些数据内部不能包含有分隔组件的保留字符,否则就会导致整个URI中组件的分隔混乱。因此对于单个组件使用encodeURIComponent,需要编码的字符就更多了。

      

    总结:

      escape函数基本上被废弃,尽量不要使用。

      encodeURI和encodeURIComponent都是使用utf-8进行URL编码。并且对各自的安全字符不会进行编码。两者的安全字符范围不同,如前面所说。

      encodeURI不会对URL中的某些特殊字符进行编码,比如:/?&=@等等。因此可用于对整个URL进行编码。这里说的某些字符就是encodeURI比encodeURIComponent多了的11个安全字符

      encodeURIComponent会对URL中的某些特殊字符进行编码,只能对某个URL组件或者子组件进行编码。比如传递参数中的值。

    实例

    由以上实例可以看出,当URL组件或者子组件内部不包含某些特殊字符时,可以直接使用encodeURI对整个URL进行编码,

    如果URL当URL组件或者子组件内部包含某些特殊字符时,则不能使用encodeURI对整个URL进行编码,而是需要使用encodeURIComponent分别对各个组件或者子组件进行编码

    另外,很多HTTP监视工具或者浏览器地址栏等在显示Url的时候会自动将Url进行一次解码(使用UTF-8字符集),这就是为什么当你在Firefox中访问Google搜索中文的时候,地址栏显示的Url包含中文的缘故。但实际上发送给服务端的原始Url还是经过编码的。你可以在地址栏上使用Javascript访问location.href就可以看出来了。在研究Url编解码的时候千万别被这些假象给迷惑了。

  • 相关阅读:
    poj 2488 DFS
    畅通工程 并查集模版
    KMP 模板
    poj 1426 DFS
    poj 2528 线段数
    poj 3468 线段数 修改区间(点)
    CVPR2012文章阅读(2)A Unified Approach to Salient Object Detection via Low Rank Matrix Recovery
    如何制定目标
    Saliency Map 最新综述
    计算机视觉模式识别重要会议杂志
  • 原文地址:https://www.cnblogs.com/gaoBlog/p/11589534.html
Copyright © 2011-2022 走看看