java js html编码与解码问题

js中编码与解码:
网上转的:http://www.cnblogs.com/hubcarl/archive/2009/04/11/1433707.html

escape(), encodeURI()和encodeURIComponent()是在Javascript中用于编码字符串的三个常用的方法
escape() 方法

escape方法以Unicode格式返回一个包含传入参数内容的string类型的值。 Escape方法会将传入参数中所有的空格、标点符号、重音字符以及其它任何非ASCII字符替换为%xx的编码形式,其中xx与其所表示的字符的16进制数表示形式相同。如空格字符的16进制表示形式为0x20,则此时xx应为20,即escape(‘ ’) 返回“%20”。

escape和unescape方法能够帮助你编码和解码字符串。escape方法对于ISO Latin字符集中的字符组成的参数,返回其16进制编码。相对应的,unescape方法则能将16进制编码形式的参数转化成为其ASCII码形式。

encodeURI()方法

encodeURI方法返回一个经过编码的URI。如果将encodeURI方法的编码结果传递给decodeURI方法作参数,则能得到原始的未编码的字符串。需要注意到是encodeURI方法不编码如下字符":", "/", ";", "?"。如果想要编码这些字符,请使用encodeURIComponent方法。通过将每个属于特定的字符集合的字符替换为一个、两个或者三个(为什么是“一个、两个或者三个”本人也没有搞懂,望高人赐教)使用UTF-8编码来表示这个字符的escape序列来编码一个URI。如 ~!@#$%^&*(){}[]=:/,;?+\''"\\ 将被替换为 ~!@#$%25%5E&*()%7B%7D%5B%5D=:/,;?+''%22%5C

encodeURIComponent()方法

encodeURIComponent方法返回一个编码过的URI。如果将encodeURIComponent方法的编码结果传递给encodeURIComponent方法作参数,则能得到原始的未编码的字符串。因为encodeURIComponent方法会编码所有的字符,所以如果待编码的字符串是用来表示一个路径(如/dir1/dir2/index.htm)时,就一定要小心使用了。‘/’符号会被其编码之后,将不再是一个有效的路径标识符,所以不能被web服务器正确地识别。当字符串包含一个单独的URI component(指?后面的请求参数)的时候,请使用此方法。通过将每个属于特定的字符集合的字符替换为一个、两个或者三个(为什么是“一个、两个或者三个”本人也没有搞懂,望高人赐教)使用UTF-8编码来表示这个字符的escape序列来编码一个URIComponent。

有什么区别?何时使用?
 
escape方法并不编码字符+。而我们知道,在用户提交的表单字段中,如果有空格,则会被转化为+字符,而服务器解析的时候则会认为+号代表空格。由于这个缺陷,escape方法并不能正确地处理所有的非ASCII字符,你应当尽量避免使用escape方法,取而代之,你最好选择encodeURIComponent()方法。
escape()不编码的字符:@*/+

相对于使用escape方法,使用encodeURI方法会显得更专业一些。当你需要编码一整个URI的时候,你可以使用此方法,因为URI中的合法字符都不会被编码转换。需要注意到是字符’也是URI中的合法字符,所以也不会被编码转换。
encodeURI() 不编码的字符: ~!@#$&*()=:/,;?+''

encodeURIComponent方法在编码单个URIComponent(指请求参数)应当是最常用的。需要注意到是字符’也是URI中的合法字符,所以也不会被编码转换。
encodeURIComponent()不编码的字符: ~!*()''

下面是自己写的
再看下jdk文档里的编码和解码:

public class URLEncoder
     
     
     
     
extends Object
 
  

HTML 格式编码的实用工具类。该类包含了将 String 转换为 application/x-www-form-urlencoded MIME 格式的静态方法。有关 HTML 格式编码的更多信息,请参阅 HTML 规范。

对 String 编码时,使用以下规则:

  • 字母数字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。
  • 特殊字符 "."、"-"、"*" 和 "_" 保持不变。
  • 空格字符 " " 转换为一个加号 "+"。
  • 所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。然后每个字节用一个包含 3 个字符的字符串 "%xy" 表示,其中 xy 为该字节的两位十六进制表示形式。推荐的编码机制是 UTF-8。但是,出于兼容性考虑,如果未指定一种编码,则使用相应平台的默认编码。

例如,使用 UTF-8 编码机制,字符串 "The string ü@foo-bar" 将转换为 "The+string+%C3%BC%40foo-bar",因为在 UTF-8 中,字符 ü 编码为两个字节,C3 (十六进制)和 BC (十六进制),字符 @ 编码为一个字节 40 (十六进制)。

public class URLDecoder
     
     
     
     
extends Object
 
  

HTML 格式解码的实用工具类。该类包含了将 String 从 application/x-www-form-urlencoded MIME 格式解码的静态方法。

该转换过程正好与 URLEncoder 类使用的过程相反。假定已编码的字符串中的所有字符为下列之一:"a" 到 "z"、"A" 到 "Z"、"0" 到 "9" 和 "-"、"_"、"." 以及 "*"。允许有 "%" 字符,但是将它解释为特殊转义序列的开始。

转换中使用以下规则:

  • 字母数字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。
  • 特殊字符 "."、"-"、"*" 和 "_" 保持不变。
  • 加号 "+" 转换为空格字符 " "。
  • 将把 "%xy" 格式序列视为一个字节,其中 xy 为 8 位的两位十六进制表示形式。然后,所有连续包含一个或多个这些字节序列的子字符串,将被其编码可生成这些连续字节的字符所代替。可以指定对这些字符进行解码的编码机制,或者如果未指定的话,则使用平台的默认编码机制。

该解码器处理非法字符串有两种可能的方法。一种方法是不管该非法字符,另一种方法是抛出 IllegalArgumentException 异常。解码器具体采用哪种方法取决于实现。


现在的问题是:服务器返回字符到页面,页面又调用js,这个时候肯定要转义下,这是相对比较简单的需求。
服务器只需借助于apache commons包里的StringEscapeUtils类,在struts2里其实已经集成在xwrok包。
StringEscapeUtils.escapeJavaScript(returnString);
这样就可以搞定这个问题。
另外也可以用js去处理这个问题,不过没有实践,主要是自己js水平有点差,
escapeJavaScript对应的源码如下:

private   static   void  escapeJavaStyleString(Writer out, String str,  boolean  escapeSingleQuote,
            
boolean  escapeForwardSlash)  throws  IOException  {
        
if (out == null{
            
throw new IllegalArgumentException("The Writer must not be null");
        }

        
if (str == null{
            
return;
        }

        
int sz;
        sz 
= str.length();
        
for (int i = 0; i < sz; i++{
            
char ch = str.charAt(i);

            
// handle unicode
            if (ch > 0xfff{
                out.write(
"\\u" + hex(ch));
            }
 else if (ch > 0xff{
                out.write(
"\\u0" + hex(ch));
            }
 else if (ch > 0x7f{
                out.write(
"\\u00" + hex(ch));
            }
 else if (ch < 32{
                
switch (ch) {
                    
case '\b' :
                        out.write(
'\\');
                        out.write(
'b');
                        
break;
                    
case '\n' :
                        out.write(
'\\');
                        out.write(
'n');
                        
break;
                    
case '\t' :
                        out.write(
'\\');
                        out.write(
't');
                        
break;
                    
case '\f' :
                        out.write(
'\\');
                        out.write(
'f');
                        
break;
                    
case '\r' :
                        out.write(
'\\');
                        out.write(
'r');
                        
break;
                    
default :
                        
if (ch > 0xf{
                            out.write(
"\\u00" + hex(ch));
                        }
 else {
                            out.write(
"\\u000" + hex(ch));
                        }

                        
break;
                }

            }
 else {
                
switch (ch) {
                    
case '\'' :
                        if (escapeSingleQuote) {
                            out.write(
'\\');
                        }

                        out.write(
'\'');
                        break;
                    
case '"' :
                        out.write(
'\\');
                        out.write(
'"');
                        
break;
                    
case '\\' :
                        out.write(
'\\');
                        out.write(
'\\');
                        
break;
                    
case '/' :
                        
if (escapeForwardSlash) {
                            out.write(
'\\');
                        }

                        out.write(
'/');
                        
break;
                    
default :
                        out.write(ch);
                        
break;
                }

            }

        }

    }

可以用js去实现也是一样的,网上也有类似的js代码。

出现的问题描述:服务器返了string,经过escapeJavaScript处理后到js代码,js代码又要用这些string去输出html.比如img的src为js处理后的字符串,
最后经过测试得出以上语句去处理这些问题:
string=encodeURIComponent(string).replace(/@/g,'%40').replace(/'/g,"'").replace(/"/g,'"');
转化@是为了获取服务器资源,比如图片地址,可以正常输出。其实输出时后面的转化单引号和双引号是为了保险起见。比如<img src='*****.jpg'/>这时就只需要转化单引号就可以了,这里主要是针对图片的处理来做的,@在其它地方有没有必要转化没有测试,如果要显示图片,得转化。

出现的问题描述:带特殊字符串的图片名要正常显示出来,得转化下:比如要显示文件名为:~!@#¥%……&*()——+.jpg的图片,代码如下:
java.net.URLEncoder.encode(photoName,"utf-8")).replace("+", "%20"),转化时因为URLEncoder把空格转化成了+,所以最后得把+替换回去,20是十六进制的,相当于十进制的32,即对应为空格。
经过转化后,图片带特殊字符就能正常显示。



天苍苍,野茫茫,风吹草底见牛羊

你可能感兴趣的:(java js html编码与解码问题)