JS的URL编码
背景
URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号,这是网络标准:
只有字母和数字[-9a-zA-Z]、一些特殊符号"$-_.+!*'(),"[不包括双引号]、以及某些保留字(;/?:@&=),才可以不经过编码直接用于URL。
这意味着,如果URL中有特殊字符,就必须编码后使用。但是麻烦的是,标准中未规定具体的编码方法,而是交给应用程序(浏览器)自己决定。这导致"URL编码"成为了一个混乱的领域。
接下来会依次分析三种不同的情况,在每种情况中,浏览器的URL编码方法都不一样。把它们的差异解释清楚之后,我再说如何用Javascript找到一个统一的编码方法。
浏览器的URL编码方法
一、网络路径中包含特殊字符
打开Chrome浏览器,输入"http://www.cnblogs.com/yangzhinian/技术",最终在控制台中请求的URL为:http://www.cnblogs.com/yangzhinian/%E6%8A%80%E6%9C%AF
Firefox的也是同样的结果,最终我们来验证使用的是什么编码方式
decodeURIComponent("http://www.cnblogs.com/yangzhinian/%E6%8A%80%E6%9C%AF");
//结果为:http://www.cnblogs.com/yangzhinian/技术
结论1:网址路径的编码,用的是utf-8编码。
二、查询字符串包含特殊字符
在window 7操作系统下,在Chrome、Firefox浏览器中,输入"http://www.cnblogs.com/yangzhinian?wd=春节",最终在控制台中请求的URL为:
http://www.cnblogs.com/yangzhinian/?wd=%E6%98%A5%E8%8A%82
但是在window XP操作系统中,Chrome、Firefox浏览器url为:
http://www.cnblogs.com/yangzhinian/?wd=%B4%BA%BD%DA
结论2:查询字符串的编码,用的是操作系统的默认编码。
三、Get、POST方法生成的URL包含特殊字符
前面说的是直接输入网址的情况,但是更常见的情况是,在已打开的网页上,直接用Get或Post方法发出HTTP请求。根据台湾中兴大学吕瑞麟老师的试验,这时的编码方法由网页的编码决定,也就是由HTML源码中字符集的设定决定。
<meta http-equiv="Content-Type" content="text/html;charset=xxxx" />
如果上面这一行最后的charset是UTF-8,则URL就以UTF-8编码;如果是GB2312,URL就以GB2312编码。
举例来说,百度是GB2312编码,Google是UTF-8编码。因此,从它们的搜索框中搜索同一个词"春节",生成的查询字符串是不一样的。
结论3:GET和POST方法的编码,用的是网页的编码。
四、Ajax调用的URL包含特殊字符
前面三种情况都是由浏览器发出HTTP请求,最后一种情况则是由Javascript生成HTTP请求,也就是Ajax调用。还是根据吕瑞麟老师的文章,在这种情况下,IE和Firefox的处理方式完全不一样。
举例来说,有这样两行代码:
url = url + "?q=" +document.myform.elements[0].value; // 假定用户在表单中提交的值是"春节"这两个字
http_request.open('GET', url, true);
那么,无论网页使用什么字符集,IE传送给服务器的总是"q=%B4%BA%BD%DA",而Firefox传送给服务器的总是"q=%E6%98%A5%E8%8A%82"。
结论4:在Ajax调用中,IE总是采用GB2312编码(操作系统的默认编码),而Firefox、Chrome总是采用utf-8编码。
Javascript编码解码方法
假定前面你都看懂了,那么此时你应该会感到很头痛。因为实在太混乱了。不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。如果程序员要把每一种结果都考虑进去,是不是太恐怖了?有没有办法,能够保证客户端只用一种编码方法向服务器发出请求?
回答是有的,就是使用Javascript先对URL编码,然后再向服务器提交,不要给浏览器插手的机会。因为Javascript的输出总是一致的,所以就保证了服务器得到的数据是格式统一的。
Javascript语言用于编码的函数,一共有三个:escape/encodeURI/encodeURIComponent。最古老的一个就是escape(),虽然这个函数现在已经不提倡使用了,但是由于历史原因,很多地方还在使用它。
一、escape/unescape
escape:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:*@-_+./ 。其他所有的字符都会被转义序列替换。
unescape:是escape对应的解码方法。
实际上,escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。
如:"春节"的返回结果是%u6625%u8282,也就是说在Unicode字符集中,"春"是第6625个(十六进制)字符,"节"是第8282个(十六进制)字符。
escape("春节"); //结果:%u6625%u8282 unescape("%u6625%u8282"); //结果:春节
注意:escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心
二、encodeURI/decodeURI
encodeURI:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:-_.!~*'() 。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 方法是不会进行转义的:;/?:@&=+$,#。
decodeURI:是encodeURI对应的解码方法。如:
encodeURI("春节");//结果:%E6%98%A5%E8%8A%82 decodeURI("%E6%98%A5%E8%8A%82");//结果:春节
三、encodeURIComponent/decodeURIComponent
encodeURIComponent:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:-_.!~*'() 。其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
decodeURIComponent:是encodeURIComponent对应的解码方法。如:
encodeURIComponent('春节');//结果:%E6%98%A5%E8%8A%82 decodeURIComponent("%E6%98%A5%E8%8A%82");//结果:"春节"
JS的URL编码的更多相关文章
- JS中URL编码参数(UrlEncode)
JS中URL编码参数(UrlEncode) 网上有很多文字作品写涉及在JS中呈现类似UrlEncode功能时都是自定义参数来呈现,其实JS中本身就有那样的参数.参数parameter由于用类似URL的 ...
- js 原生url编码
参考:http://www.runoob.com/jsref/jsref-decodeuricomponent.html
- 【转】关于URL编码/javascript/js url 编码/url的三个js编码函数
来源:http://www.cnblogs.com/huzi007/p/4174519.html 关于URL编码/javascript/js url 编码/url的三个js编码函数escape(),e ...
- Node.js superagent 采集 URL 编码问题
今天在用Node学习采集的时候遇到一个问题,如这个链接地址 http://www.meishij.net/胡萝卜 就是用浏览器的方式访问链接可以打开,但用superagent 去模拟请求,就请求不到 ...
- 关于URL编码/javascript/js url 编码/url的三个js编码函数
关于URL编码/javascript/js url 编码/url的三个js编码函数escape(),encodeURI(),encodeURIComponent() 本文为您讲述关于js(javasc ...
- js对url的编码和解码
最近做公众号相关, 需要在公众号里面配菜单, 才发现菜单的链接部分是编码过的, 如这样http%3A%2F%2Fw3cschool.cn%2Fmy%20test.asp%3Fname%3Dst%C3% ...
- JS对URL字符串进行编码/解码分析
一.为什么要进行js编码和解码? 只有字母和数字[0-9a-zA-Z].一些特殊符号“$-_.+!*'(),”[不包括双引号].以及某些保留字,才可以不经过编码直接用于URL. 出现的情况: 网址路径 ...
- JS URL编码
JS URL编码escape() 方法: 采用ISO Latin字符集对指定的字符串进行编码.所有的空格符.标点符号.特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在 ...
- Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php
Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php 1. RFC2396标准 including HTML 4.01 section ...
随机推荐
- android 自定义 view 和 ViewGroup
---恢复内容开始--- ViewGroup的职能为:给childView计算出建议的宽和高和测量模式 :决定childView的位置:为什么只是建议的宽和高,而不是直接确定呢,别忘了childVie ...
- 一个动画 Label (走马观花)
UILabel中一个水平移动的Label UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 300, 300)]; U ...
- 洛谷 P1433 吃奶酪 Label:dfs && 剪枝Ex
题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块 ...
- jsonkit mrc于arc混编
- linux 中修改root的密码
修改root密码 有的时候会出现忘记了root 用户密码的情况,再次我们可以通过进入single(单)用户模式,将root的密码重新设置,然后重启登录即可. 具体流程: 1.先登录root用户(密码已 ...
- Selenium_Selenium WebDriver 中鼠标和键盘事件分析及扩展
在使用 Selenium WebDriver 做自动化测试的时候,会经常模拟鼠标和键盘的一些行为.比如使用鼠标单击.双击.右击.拖拽等动作:或者键盘输入.快捷键使用.组合键使用等模拟键盘的操作.在 W ...
- 转自:C#中TextBox水印提示的简单实现
本文转自: 原作者: js2854 出处: http://js2854.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接 ...
- nodejs模仿http请求组件nodegrass简单例子
1.搭建nodejs环境. 2.执行npm install nodegrass命令. 3.引入模块,var ng= require(nodegrass); 4.下面先看nodegrass底层的get方 ...
- HDU 1018 大数(求N!的位数/相加)
Big Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- Hibernate和Mybatis的对比
http://blog.csdn.net/jiuqiyuliang/article/details/45378065 Hibernate与Mybatis对比 1. 简介 Hibernate:Hiber ...