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 ...
随机推荐
- DOM操作优化
文档对象模型(DOM)是一个独立 于特定语言的应用程序接口.在浏览器中,DOM接口是以JavaScript语言实现的,通过JavaScript来操作浏览器页面中的元素,这使得 DOM成为了JavaSc ...
- exp.validate.js
简单实用的js基础数据验证 prototype /// <reference path="/Scripts/expand-fn/exp_validate.js" /> ...
- Flex——Array,ArrayCollection,Vector性能比较(转)
测试方法 private function Test():void { ;j<;j++) { trace("插入10000项============"); var t1:in ...
- validation插件
1.项目下载地址:http://plugins.jquery.com/validation/ 2.引入 <script type="text/javascript" src= ...
- 兼容所有浏览器的设为首页收藏本站js代码
大家发现传统的收藏本站按钮在360浏览器下面没有效果了,但是360浏览器用户群却非常之大.所以我们在网上找到一个兼容所有浏览器的收藏本站解决方案,具体功能如下: 设为首页 和 收藏本站js代码 兼容I ...
- cat 显示指定行
[一]从第3000行开始,显示1000行.即显示3000~3999行 cat filename | tail -n +3000 | head -n 1000 [二]显示1000行到3000行 cat ...
- 用一段JS代码来比较各浏览器的极限内存与运算速度
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- android之消息机制(二)
消息通道:Looper 首先编写main.xml文件 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk ...
- SubmitText 中配置lua 运行环境
一 新建编译系统 二.使用新建的编译系统 三配置 { "cmd": ["lua", "$file"], "file_regex&q ...
- layoutSubviews #pragma mark -
>>>layoutSubviews: layoutSubviews是对sbuviews的重新布局,比如,我们想更新子视图的位置,可以通过调用layoutSubviews方法(不能直接 ...