URL编解码

    URI(统一资源定为标志),用于指定想要访问的资源,URI可以有各种形式,如:日常在用的URL、每本书背面的ISBN码都是URI的一种形式, 日常过程中,如果不加区分,一般说的URI都指的是URL。拿我们熟悉的URL来说:

一个普通的URL:

https://www.baidu.com/fuck.php?action=run#hash=1

URL一般包括以下几个部分:

  • Scheme
    指定URL协议:http/https

  • hostname
    指定域名,如上面的www.baidu.com

  • port
    指定目标主机端口号,http协议默认为80端口,https默认为433端口。
  • path
    指定要访问的资源路径,以上为fuck.php
  • query
    ?开头,传递给目标主机的参数,key/value的形式来表示参数,参数之间通过&符号间隔开来。在Nodejs服务器,上面的URL最终解析得到query对象:

    req.query = {action: run}

  • hash
    hash参数用于给浏览器渲染出来的HTML界面指定锚点,服务器在解析URL的时候会把#后面的字符丢弃。

如果在实际运用过程中我们仅仅只需要知道这些概念就好了,可惜事情的复杂度往往比现象的要大。
  • 如果要给URL放其他字符怎么处理,如果我想放一些二进制数据呢?
  • 数据量一大,URL会不会出现过长的问题?
URL编解码

    在编写js代码过程中有几个常用的URL编码函数:encodeURI, encodeURIComponent, atob。以及对应的解码函数:decodeURI, decodeURIComponent, btoa。关于编解码,官方也有明确的规定(RFC 3986文档),以下字符为保留字符,如果开发者需要使用它,就需要对其编码:

; , / ? : @ & = + $

同时也规定了一些非保留字符:

字母/数字/- _ . ! ~ * ’ ( )

对URL特殊字符的编码称之为百分号编码。即:

对于特殊字符序,需要转换为UTF-8编码方式,然后取每个字节的16进制值,在其前面加上%号,完成编码。由于UTF-8编码兼容ASCII码,所以对于特殊字符只需要取其ASCII码的16进制值,在前面加上%即可。由于%号(ASCII HEX = 25)在URL编码有特殊的含义,所以也需要对它编码:%25。最终得到的url仅仅由定义URL schema需要的字符,加上非保留字符组成。

来看看几个编解码函数的具体功能:
+ encodeURI/decodeURI
用于对整个URL编解码,但是其不会对保留字符与上面定义的非保留字符进行编码。举个例子:
普通的编码:


> var url1 = 'http://www.baidu.com/fuck.php?action=run';
undefined

> encodeURI(url1)
'http://www.baidu.com/fuck.php?action=run'
> 

加上几个保留字符试一试:


> var url1 = 'http:/$/@;www.baidu.com/fuck.php?action=run';

> encodeURI(url1)
'http:/$/@;www.baidu.com/fuck.php?action=run'
> 

可以看到并没有对保留字符编码。

再加入几个其他字符,如中文,试一试:

> var url1 = 'http:/$/@;www.baidu.com/你好fuck.php?action=run';

> encodeURI(url1)
'http:/$/@;www.baidu.com/%E4%BD%A0%E5%A5%BDfuck.php?action=run'

你好对应的Unicode码为:4F60597DUTF-8编码之后分别为:E4BDA0E5A5BD正好匹配encodeURI的输出。
可以看到对encodeURI除保留字符与特殊字符外的字符进行了编码。

由于encodeURI不会对一些特殊字符编码,但是URL规范使用中必须对一些特殊字符譬如说:&, =,+进行编码。所以我们要用到的另一个函数是encodeURIComponent

encodeURIComponent会把除非保留字符外的字符,通过百分号编码,转化为非保留字符的形式,这其中就包括了特殊字符。
看几个例子:

> var component = 'http://www.baidu.com'; 

> encodeURIComponent(component);
'http%3A%2F%2Fwww.baidu.com'
> 

:, /都是保留字符,而.以及字母是非保留字符,验证了我们的想法。

如果我们要在URL传入一些二进制数据怎么办呢?首先想到的是:Base64编码的出现主要就是为了解决二进制数据的传输问题btoa就是我们想要的接口。
举个例子:

var atob = require('atob');
var btoa = require('btoa');

var u1 = 'http://www.baidu.com';

console.log(btoa(u1));

输出:

aHR0cDovL3d3dy5iYWlkdS5jb20=

由于Base64在被编码字符长度不为3的倍数情况下会出现=号,=是保留字符,由于它在这里有特殊的含义(表示传输数据的一部分),所以需要调用encodeURIComponent对其进行编码。

URL的一些数据长度限制规定

web 浏览器对整个 URI 长度有一定的限制。传统的IE浏览器是2048个字节,而现代各种浏览器和 web 服务器的设定均不一样,这依赖于各个浏览器厂家的规定或者可以根据 web 服务器的处理能力来设定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值