一、URI && URL
说到编码,先弄清什么是URI,什么是URL?
URL是URI的子集,URI是统一资源标识符,URL是统一资源定位符。
协议名称://域名.根域名/目录/文件名.后缀
协议://域名/目录/文件#片段标示符
../文件D
二、编码函数
1、escape(string)
编码字符串,string为需要被转义或者编码的字符串,该方法不编码字符有69个,分别是:ASCII 字母,数字,* @ - _ + . /,其他所有的字符都会被替换成了十六进制的转义序列,让它们在所有电脑上可读。
解码函数:unescape(string)
2、encodeURI(URIstring)
编码整个URI(可把字符串作为 URI 进行编码),该方法不编码字符有82个,分别是:ASCII 字母,数字,- _ . ! ~ * ' ( ) ;/?:@&=+$,#。
encodeURI("http://www.cnblogs.com/camille666/js_cookie");
编码后:"http://www.cnblogs.com/camille666/js_cookie"
解码函数:decodeURI(URIstring)
3、encodeURIComponent(URIstring)
编码URI参数(可把字符串作为 URI组件进行编码),该方法不编码字符有71个,分别是: ASCII 字母,数字,- _ . ! ~ * ' ( ),编码范围比encodeURI(URIstring)大。它的参数是 URI 的一部分,比如协议、主机名、路径或查询字符串。
var param = "http://www.cnblogs.com/camille666/"; param = encodeURIComponent(param); // http%3A%2F%2Fwww.cnblogs.com%2Fcamille666%2F var url = "http://www.cnblogs.com?next=" + param; console.log(url) //http://www.cnblogs.com?next= http%3A%2F%2Fwww.cnblogs.com%2Fcamille666%2F
解码函数:decodeURIComponent(URIstring)
三、常用实例
前端开发中用到最多的应该是 encodeURIComponent/decodeURIComponent。例如下面这个将 URL Search 中的参数转化为对象的方法:
var parseUrlSearch = function() { var query = window.location.search.slice(1); var result = {}; query.split("&").forEach(function(part) { var item = part.split("="); result[item[0]] = decodeURIComponent(item[1]); }); return result; };
四、查看编码的cookie
1、Editthiscookie,然后在浏览器中打印函数encodeURIComponent(URIstring)。
2、在application里面看,然后在浏览器中打印函数encodeURIComponent(URIstring)。
3、在控制台输入document.cookie,查看。
4、去在线工具网站(http://tool.oschina.net/encode?type=2)手动复制编码的cookie,转码后查看。
5、用火狐浏览器打开网页,如果有历史记录(存在cookie),那么打开调试面板,选择【网络】,点击请求链接,选择【cookie】,即可看到“响应cookie”和“请求cookie”的信息,在“请求cookie”信息里可以看到解码的cookie。
五、不要混用编码方式
1、用escape编码,可以用unescape解码,不能用decodeURIComponent解码,否则会出现Uncaught URIError: URI malformed报错,at decodeURIComponent (<anonymous>)
2、用encodeURIComponent编码,可以用decodeURIComponent解码,可以用unescape解码,不报错,但是解码后的结果不是我们想要的结果,所以最好还是用一套编码和解码,不要混用。
六、重现编码问题具体场景
A系统(首页,频道页,采用escape编码,要实现数据共享,必须把cookie存在相同的根域名下,互通读取),B系统(manage后台,用了jquery.cookie.js文件,采用encodeURIComponent编码,存放在当前域名下),先在A系统中输入~!@#¥%……&*关键字,搜索后,在浏览器中打开B系统页面。
在谷歌浏览器中,chrome取当前域名和所有子域的cookie。查看A系统页面,在控制台看不到B系统的cookie,因为B系统的cookie存在于它自己当前的域名下,而A系统是存在根域名下。查看B系统页面,在控制台看到A系统的cookie,并且出现Uncaught URIError: URI malformed报错,原来A系统的cookie默默的被decodeURIComponent()解码了。截图如下:
然而,在火狐浏览器中,不存在这样的报错,因为火狐浏览器只取当前域名的cookie。
解决方案:更换频道页搜索编码方式,把escape全部改成encodeURIComponent编码即可。
七、深入思考
但是又有一个问题,我们都改换成encodeURIComponent后,客户端存储了用escape编码的cookie,到时候无法解读,还是会报错。我们开发环境可以手动清除cookie,但是用户不会去手动清除。
1、 难道要通知用户手动删除本地cookie吗?
2、 还是有什么办法获取客户机上cookie编码的方式,如果是escape编码,就给他提供unescape的解码方式,如果是encodeURIComponent编码,就提供decodeURIComponent解码方式。
3、要实现数据联通,除了设置domain在根域名下,还有别的方法吗?如果设置当前域名,别的站点还能够访问吗?比如首页埋在www,频道页埋在a,但是www可以访问a的cookie,a也可以访问www的cookie。