1.简单解释

  简单来说,escape是对字符串(string)进行编码(而另外两种是对URL),作用是让它们在所有电脑上可读。
  编码之后的效果是%XX或者%uXXXX这种形式。
  其中 ASCII字母、数字、@*/+ ,这几个字符不会被编码,其余的都会。
  最关键的是,当你需要对URL编码时,请忘记这个方法,这个方法是针对字符串使用的,不适用于URL。

2.   encodeURI和encodeURIComponent

  对URL编码是常见的事,所以这两个方法应该是实际中要特别注意的。
  它们都是编码URL,唯一区别就是编码的字符范围,其中
  encodeURI方法不会对下列字符编码 ASCII字母、数字、~!@#$&*()=:/,;?+'
  encodeURIComponent方法不会对下列字符编码 ASCII字母、数字、~!*()'
也就是encodeURIComponent编码的范围更广,会将http://XXX中的//也编码,会导致URL不可用。(其实java中的URLEncoder.encode(str,char)也类似于这个方法,会导致URL不可用)

3简单使用

3.1编码中文

    var param = "中文";
console.log(escape(param));
console.log(encodeURI(param));
console.log(encodeURIComponent(param));

结果:

3.2 encodeURI和encodeURIComponent编码URL

    var url = "http://localhost:85/Exam/settingAction_saveSettings.action?safeHatNumLength=测试";
console.log(encodeURI(url));
console.log(encodeURIComponent(url));

结果:

http://localhost:85/Exam/settingAction_saveSettings.action?safeHatNumLength=%E6%B5%8B%E8%AF%95
http%3A%2F%2Flocalhost%3A85%2FExam%2FsettingAction_saveSettings.action%3FsafeHatNumLength%3D%E6%B5%8B%E8%AF%95

4.使用场景

1、如果只是编码字符串,不和URL有半毛钱关系,那么用escape,而且这个方法一般不会用到。
2、如果你需要编码整个URL,然后需要使用这个URL,那么用encodeURI。
3、当你需要编码URL中的参数的时候,那么encodeURIComponent是最好方法。

5.测试URL传中文参数问题

此时tomcat的编码是iso8859-1默认编码,后台采用struts2的属性驱动接受。并且进行解码: (Java后台解码)

        System.out.println(safeHatNumLength);
try {
System.out.println(URLDecoder.decode(safeHatNumLength,"UTF-8"));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}

5.1直接在url中输入中文查看后台:

http://localhost:85/Exam/settingAction_saveSettings.action?safeHatNumLength=测试

结果:

测è¯

原因:直接访问浏览器会将中文采用utf-8编码传到后台,后台tomcat接收到之后采用iso8859-1解码所以乱码

5.2window.open不编码直接访问

    var url = "http://localhost:85/Exam/settingAction_saveSettings.action?safeHatNumLength=测试";
window.open(encodeURI(url));

结果与原因同上同上

5.3   URL中文参数两次编码得到正确结果(一次编码不能得到正确结果)

总结:参数携带中文需要两次编码,如下:

        var url = encodeURI(encodeURI("http://localhost:85/Exam/settingAction_saveSettings.do?safeHatNumLength=测试"));
console.log(url);
window.open(url);

结果:

%E6%B5%8B%E8%AF%95
测试

原因:两次编码传到后台之后,tomcat收到参数第一次进行解码之后变为一次utf-8编码的字符串,所以再次调用解码一次就变为中文。

5.4  表单get方法提交一次编码就可以

    <form id="testForm" action="/Exam/settingAction_saveSettings.do" method="get">
<input name="safeHatNumLength" />
<input type="button" value="提交" onclick="submitForm();" />
</form>
<script>
function submitForm() {
$.get("/Exam/settingAction_saveSettings.do",encodeURI($("#testForm").serialize()));
}
</script>

后台结果::

%E9%97%AE%E9%97%AE
问问

总结:  

  如果只对参数编码用encodeURIComponent编码就可以,当然用 encodeURI也可以,如果不生效可以用两次编码。

  如果是对整个URL进行编码最好用encodeURI,而且是两次编码 ,否则有可能不必生效。

  判断是否生效只需要看带到后台的参数是否是编码后的格式,或者url的地址是否是编码之后的。

补充:浏览器也可以查看默认编码:

alert(document.charset)

关于两次编码的原因:

 假设参数是一个"中"字
1.第一次encodeURI,按照utf-8方式获取字节数组变成[-28,-72-83],对字节码数组进行遍历,把每个字节转化成对应的16进制数,这样就变成了[E4,B8,AD],最后变成[%E4,%B8,%AD]

2.第二次encodeURI,把数组最后变成[%25E4,%25B8,%25AD]然后就把处理后的数据[%25E4,%25B8,%25AD]发往服务器端,

当应用服务器调用getParameter方法,getParameter方法会去向应用服务器请求参数,应用服务器最初获得的就是发送来的[%25E4,%25B8,%25AD],

应用服务器会对这个数据进行URLdecode操作,URldecode操作和encodeURL操作是相反的操作,处理结果就是[%E4,%B8,%AD],并把这个值返回给getParameter方法,然后再在服务器端中调用相应的URL转码方法或者是函数  就可以把数据还原成最初页面发送过来的中文“中”了。

URL编码与两次encodeURI

当使用地址栏提交查询参数时,如果不编码,非英文字符会按照操作系统的字符集进行编码提交到服务器,服务器会按照配置的字符集进行解码,所以如果两者不一致就会导致乱码。

encodeURI函数采用UTF-8对URL进行编码,所以如果服务器在进行解码时使用的是其他的编码方式就会出现乱码,默认的服务器配置的解码字符集都不是UTF-8,所以大部分情况下地址栏提交中文查询参数时会产生乱码;针对这种情况,可以连续使用两次encodeURI在客户端(主要指浏览器)对非英文字符进行编码,然后在服务端使用Java.NET.URLDecoder(String."UTF-8")解码,即可得到正确的中文。

如果只进行一次encodeURI,得到的是UTF-8形式的URL,服务器端通过request.getParameter()解码查询参数(通常是iso-8859-1)就会得到乱码。

如果进行两次encodeURI,第一次编码得到的是UTF-8形式的URL,第二次编码得到的依然是UTF-8形式的URL,但是在效果上相当于首先进行了一次UTF-8编码(此时已经全部转换为ASCII字符),再进行了一次iso-8859-1编码,因为对英文字符来说UTF-8编码和ISO-8859-1编码的效果相同。在服务器端,首先通过request.getParameter()自动进行第一次解码(可能是gb2312,gbk,utf-8,iso-8859-1等字符集,对结果无影响)得到ascii字符,然后再使用UTF-8进行第二次解码,通常使用java.net.URLDecoder("","UTF-8")方法。

两次编码两次解码的过程为:

UTF-8编码->UTF-8(iso-8859-1)编码->iso-8859-1解码->UTF-8解码,编码和解码的过程是对称的,所以不会出现乱码。(实际tomcat服务器收到参数之后就会进行一次解码,也就是第一次解码)

encodeURL函数主要是来对URI来做转码,它默认是采用的UTF-8的编码.
. UTF-8编码的格式:一个汉字来三个字节构成,每一个字节会转换成16进制的编码,同时添加上%号

1.首先前台测试编码效果:(验证上面的编码效果)

(1)第一次编码:

    console.log(encodeURI("中"));
console.log(encodeURI(encodeURI("中")));

结果:

%E4%B8%AD
%25E4%25B8%25AD

2.下面进行后台Java接受演示

一个简单的servlet代码:

        Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String string = (String) parameterNames.nextElement();
log.info("key -> {},value -> {}", string, request.getParameter(string));
}

(1)测试一次编码,tomcat中编码为iso8859-1(这种也无法进行解码,已经发生乱码)

直接URL中输入:   http://localhost/index.html?param=中

实际谷歌浏览器自动编码为:http://localhost/index.html?param=%E4%B8%AD

查看看后台结果:

    2018-12-27 19:09:02 [cn.ding.test.TestServlet]-[INFO] key -> param,value -> 中

(2)测试一次编码,tomcat中编码为UTF-8(一次编码后台正常接受到的就是正常的中文)

直接URL中输入:   http://localhost/index.html?param=中

实际谷歌浏览器自动编码为:http://localhost/index.html?param=%E4%B8%AD

查看看后台结果:

    2018-12-27 19:13:55 [cn.ding.test.TestServlet]-[INFO] key -> param,value -> 中

(3)测试2次编码,tomcat中编码为iso8859-1

  直接URL中输入:   http://localhost/index.html?param=%25E4%25B8%25AD

结果: (可以看出来tomcat解码了一次)

  2018-12-27 19:16:12 [cn.ding.test.TestServlet]-[INFO] key -> param,value -> %E4%B8%AD

此时如果我们用下面方法可以将参数解析为正常的中文:

URLDecoder.decode("%E4%B8%AD", "utf-8")

(4)测试2次编码,tomcat中编码为utf-8

  直接URL中输入:   http://localhost/index.html?param=%25E4%25B8%25AD

结果: (可以看出来tomcat解码了一次)

  2018-12-27 19:19:10 [cn.ding.test.TestServlet]-[INFO] key -> param,value -> %E4%B8%AD

此时如果我们用下面方法可以将参数解析为正常的中文:

URLDecoder.decode("%E4%B8%AD", "utf-8")

  通过上面明白了,实际前台encodeURI编码的次数与你后台默认的编码格式相关,如果你的后台默认是UTF-8编码,前台对中文只需要一次encodeURI即可;如果后台默认的是ios8859-1,一次编码之后将造成乱码无法还原,前台编码两次后台收到的解码一次的效果,所以才有utf-8解码一次即可还原。

  也就是你需要记住tomcat收到参数之后就会用server.xml中的编码格式进行一次解码,所以编码解码与次数问题就很好理解了。

补充:Tomcat编码问题---------------实际上此编码告诉tomcat以哪种编码解析参数

tomcat8以后默认编码格式是utf-8;7之前的都是iso8859-1

如果默认情况下,tomcat使用的的编码方式:iso8859-1

修改tomcat下的conf/server.xml文件

找到如下代码:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

这段代码规定了Tomcat监听HTTP请求的端口号等信息。

可以在这里添加一个属性:URIEncoding,将该属性值设置为UTF-8,即可让Tomcat(默认ISO-8859-1编码)以UTF-8的编码处理get请求。

修改完成后:

<Connector port="8080"  protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />

escape、encodeURI和encodeURIComponent的区别的更多相关文章

  1. JS中 escape, encodeURI 和 encodeURIComponent的区别

    为避免Url字符串在传递过程中的乱码,我们一般需要对字符串进行处理. 在Javascript中实现此功能的全局对象有3个,分别是:escape(),  encodeURI()  和 encodeURI ...

  2. escape encodeURI和encodeURIComponent的区别

    escape(与之对应->unescape) escape是对字符串(string)进行编码(而另外两种是对URL),作用是让它们在所有电脑上可读.编码之后的效果是%XX或者%uXXXX这种形式 ...

  3. escape(), encodeURI()和encodeURIComponent()(转)

      escape(), encodeURI()和encodeURIComponent()是在Javascript中用于编码字符串的三个常用的方法,而他们之间的异同却困扰了很多的Javascript初学 ...

  4. encodeURI与encodeURIComponent的区别

    webservice输出时选择的格式与Content-Type报文头有关 encodeURI与encodeURIComponent的区别:后者会将URI进行编码(包括"://")

  5. Javascript中escape(), encodeURI()和encodeURIComponent()之精析与比较

    escape(), encodeURI()和encodeURIComponent()是在Javascript中用于编码字符串的三个常用的方法,而他们之间的异同却困扰了很多的Javascript初学者, ...

  6. escape、encodeURI和encodeURIComponent的区别及使用

    编码 javascript中的编码函数有三种 escape(string) encodeURI(string) encodeURIComponent(string) 解码 相应的解码函数也有以下三种 ...

  7. 深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例

    JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...

  8. Javascript中escape()、encodeURI()、encodeURIComponent()的区别

    JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...

  9. js 中escape,encodeURI,encodeURIComponent的区别

    escape:方法不能能够用来对统一资源(URI)进行编码,对其编码应使用encodeURI和encodeURIComponent encodeURI:encodeURI ()方法返回一个编码的 UR ...

随机推荐

  1. Minimum Cost POJ - 2516 (模板题 spfa最小费用最大流)

    题意: 人回家,一步一块钱,有x个人,y个房子,求能回家的最大人数且使之费用最小 解析: 就是....套模板,,,, 建图(⊙﹏⊙)...要仔细观察呐 对于人拆不拆都可以  都能过,,,,这里贴上拆开 ...

  2. hdu 6393 Traffic Network in Numazu (树链剖分+线段树 基环树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6393 思路:n个点,n条边,也就是基环树..因为只有一个环,我们可以把这个环断开,建一个新的点n+1与之相 ...

  3. 洛谷P3628 [APIO2010]特别行动队(动态规划,斜率优化,单调队列)

    洛谷题目传送门 安利蒟蒻斜率优化总结 由于人是每次都是连续一段一段地选,所以考虑直接对\(x\)记前缀和,设现在的\(x_i=\)原来的\(\sum\limits_{j=1}^ix_i\). 设\(f ...

  4. Android 安装 卸载 更新 程序

    安装程序的方法: .通过Intent机制,调出系统安装应用,重新安装应用的话,会保留原应用的数据. 1. String fileName =Environment.getExternalStorage ...

  5. 【BZOJ3129】[SDOI2013]方程(容斥,拓展卢卡斯定理)

    [BZOJ3129][SDOI2013]方程(容斥,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 因为答案是正整数,所先给每个位置都放一个就行了,然后\(A\)都要减一. 大于的限制和没有的区别不大, ...

  6. 洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX 解题报告

    P1337 [JSOI2004]平衡点 / 吊打XXX 题目描述 有 \(n\) 个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.\(X\)处就是公共的绳结.假设 ...

  7. 洛谷 P2679 子串 解题报告

    P2679 子串 题目描述 有两个仅包含小写英文字母的字符串\(A\)和\(B\). 现在要从字符串\(A\)中取出\(k\)个互不重叠的非空子串,然后把这\(k\)个子串按照其在字符串\(A\)中出 ...

  8. 移动端利用-webkit-box水平垂直居中

    首先,必须要在父元素上用display:-webkit-box. 一.box的属性: 1.box-orient 用于父元素,用来确定父容器里子容器的排列方式,是水平还是垂直. horizontal在水 ...

  9. 【模板】Tarjan scc缩点

    代码如下 #include <bits/stdc++.h> using namespace std; const int maxv=1e4+10; const int maxe=1e5+1 ...

  10. mysql常见问题解决

    日常使用mysql数据库遇到的一些问题,做下记录,会持续更新. 一.MySql Host is blocked because of many connection errors; unblock w ...