混乱的url编码||URL编码解码问题
转载自:http://www.ruanyifeng.com/blog/2010/02/url_encoding.html
一。问题的由来。 url就是网址,只要上网就一定会用到。 一般来说,URL只能使用英文字母,阿拉伯数字和某些标点符号,不能使用其他文字和符号。 比如,世界上有英文字母的网址,http://www.xyz.com' 但是没有希腊文的网址http://aerfa,beita,segma.com。这是因为网络 标准RFC 1738做了硬性规定: 只有字母和数字[0-9a-zA-Z], 一些特殊符号$-_.+!*'(),以及某些保留字,才可以不经过编码直接用于URL 这意味着,如果URL中有汉字,就必须编码后使用。但是麻烦的是RFC_1738没有规定具体的编码方法,而是交给应用程序‘浏览器’自己决定。 这导致url编码成为一个混乱的区域。 下面就让我们看看,“URL”编码到底有多混乱。我会依次分析四种不同的情况,在每一种情况中,浏览器的编码方法都不一样。 把他们的差异解释清楚之后,我再说如何用javascript找到一个统一的编码方法。 1, http://zh.wikipedia.org/wiki/春节 结论1;网址路劲的编码,用的是utf8编码 2,http://www.baidu.com/s?wd=春节 结论2:查询字符串的编码,用的是操作系统的默认编码。 3,在浏览器直接输入春节 baidu google 结论3:get和post方法的编码,用的是网页的编码 4,ajax调用的url包含汉字 ex: url=url+"?q=" + document.form.getelements[0].value. //假设表达提交的为春节。 http_request.open('GET', url, true); 结论4:在ajax调用中,ie总是采用GB2312编码(即操作系统默认编码), 而firefox总是采用utf-8编码。
=========================================================================================
linux
origin: http://www.baidu.com/s?wd=魔兽
normalize: www.baidu.com/s?wd=魔兽
re-url_encoded: www.baidu.com/s?wd=%E9%AD%94%E5%85%BD
firefox:
https://www.baidu.com/s?wd=%E9%AD%94%E5%85%BD
windows下的编码:
linux(默认utf8)
wd=%E9%AD%94%E5%85%BD
void test_encoding(std::string& url) { std::cout << "origin: " << url << std::endl; char url_normal[1024]; int z = normalize(url.c_str(), url_normal, sizeof(url_normal)); //将url中非保留字及允许的ascii码 if(z==1){ std::cout << "normalize: " << url_normal << std::endl; char* p = slu::reencode_escapes(url_normal); std::cout << "re-url_encoded: " << p << std::endl; delete[] p; }else{ std::cout << "valid url : " << url << std::endl; } }
origin: http://zhidao.baidu.com/search?word=%C8%E7%BA%CE%C9%BE%B3%FD%B0%D9%B6%C8%D6%AA%B5%C0%D7%A8%D2%B5qq1036363060&ie=gbk&site=-1&sites=0&date=0&pn=90
normalize: zhidao.baidu.com/search?word=ɾҵqq1036363060&ie=gbk&site=-1&sites=0&date=0&pn=90
re-url_encoded: zhidao.baidu.com/search?word=%C8%E7%BA%CE%C9%BE%B3%FD%B0%D9%B6%C8%D6%AA%B5%C0%D7%A8%D2%B5qq1036363060&ie=gbk&site=-1&sites=0&date=0&pn=90
图中:为乱码
结论:
escape类函数,其实仅仅是把url非保留字符全部(添加%转义)了, 实际的二进制并没有变。