asdtiang的博客 感謝blogjava提供的博客交流平臺(tái)

          java js html編碼與解碼問(wèn)題

          Posted on 2011-05-05 11:07 asdtiang 閱讀(3913) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA
          js中編碼與解碼:
          網(wǎng)上轉(zhuǎn)的:http://www.cnblogs.com/hubcarl/archive/2009/04/11/1433707.html

          escape(), encodeURI()和encodeURIComponent()是在Javascript中用于編碼字符串的三個(gè)常用的方法
          escape() 方法

          escape方法以Unicode格式返回一個(gè)包含傳入?yún)?shù)內(nèi)容的string類型的值。 Escape方法會(huì)將傳入?yún)?shù)中所有的空格、標(biāo)點(diǎn)符號(hào)、重音字符以及其它任何非ASCII字符替換為%xx的編碼形式,其中xx與其所表示的字符的16進(jìn)制數(shù)表示形式相同。如空格字符的16進(jìn)制表示形式為0x20,則此時(shí)xx應(yīng)為20,即escape(‘ ’) 返回“%20”。

          escape和unescape方法能夠幫助你編碼和解碼字符串。escape方法對(duì)于ISO Latin字符集中的字符組成的參數(shù),返回其16進(jìn)制編碼。相對(duì)應(yīng)的,unescape方法則能將16進(jìn)制編碼形式的參數(shù)轉(zhuǎn)化成為其ASCII碼形式。

          encodeURI()方法

          encodeURI方法返回一個(gè)經(jīng)過(guò)編碼的URI。如果將encodeURI方法的編碼結(jié)果傳遞給decodeURI方法作參數(shù),則能得到原始的未編碼的字符串。需要注意到是encodeURI方法不編碼如下字符":", "/", ";", "?"。如果想要編碼這些字符,請(qǐng)使用encodeURIComponent方法。通過(guò)將每個(gè)屬于特定的字符集合的字符替換為一個(gè)、兩個(gè)或者三個(gè)(為什么是“一個(gè)、兩個(gè)或者三個(gè)”本人也沒(méi)有搞懂,望高人賜教)使用UTF-8編碼來(lái)表示這個(gè)字符的escape序列來(lái)編碼一個(gè)URI。如 ~!@#$%^&*(){}[]=:/,;?+\''"\\ 將被替換為 ~!@#$%25%5E&*()%7B%7D%5B%5D=:/,;?+''%22%5C

          encodeURIComponent()方法

          encodeURIComponent方法返回一個(gè)編碼過(guò)的URI。如果將encodeURIComponent方法的編碼結(jié)果傳遞給encodeURIComponent方法作參數(shù),則能得到原始的未編碼的字符串。因?yàn)閑ncodeURIComponent方法會(huì)編碼所有的字符,所以如果待編碼的字符串是用來(lái)表示一個(gè)路徑(如/dir1/dir2/index.htm)時(shí),就一定要小心使用了。‘/’符號(hào)會(huì)被其編碼之后,將不再是一個(gè)有效的路徑標(biāo)識(shí)符,所以不能被web服務(wù)器正確地識(shí)別。當(dāng)字符串包含一個(gè)單獨(dú)的URI component(指?后面的請(qǐng)求參數(shù))的時(shí)候,請(qǐng)使用此方法。通過(guò)將每個(gè)屬于特定的字符集合的字符替換為一個(gè)、兩個(gè)或者三個(gè)(為什么是“一個(gè)、兩個(gè)或者三個(gè)”本人也沒(méi)有搞懂,望高人賜教)使用UTF-8編碼來(lái)表示這個(gè)字符的escape序列來(lái)編碼一個(gè)URIComponent。

          有什么區(qū)別?何時(shí)使用?
           
          escape方法并不編碼字符+。而我們知道,在用戶提交的表單字段中,如果有空格,則會(huì)被轉(zhuǎn)化為+字符,而服務(wù)器解析的時(shí)候則會(huì)認(rèn)為+號(hào)代表空格。由于這個(gè)缺陷,escape方法并不能正確地處理所有的非ASCII字符,你應(yīng)當(dāng)盡量避免使用escape方法,取而代之,你最好選擇encodeURIComponent()方法。
          escape()不編碼的字符:@*/+

          相對(duì)于使用escape方法,使用encodeURI方法會(huì)顯得更專業(yè)一些。當(dāng)你需要編碼一整個(gè)URI的時(shí)候,你可以使用此方法,因?yàn)閁RI中的合法字符都不會(huì)被編碼轉(zhuǎn)換。需要注意到是字符’也是URI中的合法字符,所以也不會(huì)被編碼轉(zhuǎn)換。
          encodeURI() 不編碼的字符: ~!@#$&*()=:/,;?+''

          encodeURIComponent方法在編碼單個(gè)URIComponent(指請(qǐng)求參數(shù))應(yīng)當(dāng)是最常用的。需要注意到是字符’也是URI中的合法字符,所以也不會(huì)被編碼轉(zhuǎn)換。
          encodeURIComponent()不編碼的字符: ~!*()''

          下面是自己寫的
          再看下jdk文檔里的編碼和解碼:

          public class URLEncoder
          extends Object
          
          

          HTML 格式編碼的實(shí)用工具類。該類包含了將 String 轉(zhuǎn)換為 application/x-www-form-urlencoded MIME 格式的靜態(tài)方法。有關(guān) HTML 格式編碼的更多信息,請(qǐng)參閱 HTML 規(guī)范

          對(duì) String 編碼時(shí),使用以下規(guī)則:

          • 字母數(shù)字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不變。
          • 特殊字符 "."、"-"、"*" 和 "_" 保持不變。
          • 空格字符 " " 轉(zhuǎn)換為一個(gè)加號(hào) "+"。
          • 所有其他字符都是不安全的,因此首先使用一些編碼機(jī)制將它們轉(zhuǎn)換為一個(gè)或多個(gè)字節(jié)。然后每個(gè)字節(jié)用一個(gè)包含 3 個(gè)字符的字符串 "%xy" 表示,其中 xy 為該字節(jié)的兩位十六進(jìn)制表示形式。推薦的編碼機(jī)制是 UTF-8。但是,出于兼容性考慮,如果未指定一種編碼,則使用相應(yīng)平臺(tái)的默認(rèn)編碼。

          例如,使用 UTF-8 編碼機(jī)制,字符串 "The string ü@foo-bar" 將轉(zhuǎn)換為 "The+string+%C3%BC%40foo-bar",因?yàn)樵?UTF-8 中,字符 ü 編碼為兩個(gè)字節(jié),C3 (十六進(jìn)制)和 BC (十六進(jìn)制),字符 @ 編碼為一個(gè)字節(jié) 40 (十六進(jìn)制)。

          public class URLDecoder
          extends Object
          
          

          HTML 格式解碼的實(shí)用工具類。該類包含了將 String 從 application/x-www-form-urlencoded MIME 格式解碼的靜態(tài)方法。

          該轉(zhuǎn)換過(guò)程正好與 URLEncoder 類使用的過(guò)程相反。假定已編碼的字符串中的所有字符為下列之一:"a" 到 "z"、"A" 到 "Z"、"0" 到 "9" 和 "-"、"_"、"." 以及 "*"。允許有 "%" 字符,但是將它解釋為特殊轉(zhuǎn)義序列的開(kāi)始。

          轉(zhuǎn)換中使用以下規(guī)則:

          • 字母數(shù)字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不變。
          • 特殊字符 "."、"-"、"*" 和 "_" 保持不變。
          • 加號(hào) "+" 轉(zhuǎn)換為空格字符 " "。
          • 將把 "%xy" 格式序列視為一個(gè)字節(jié),其中 xy 為 8 位的兩位十六進(jìn)制表示形式。然后,所有連續(xù)包含一個(gè)或多個(gè)這些字節(jié)序列的子字符串,將被其編碼可生成這些連續(xù)字節(jié)的字符所代替??梢灾付▽?duì)這些字符進(jìn)行解碼的編碼機(jī)制,或者如果未指定的話,則使用平臺(tái)的默認(rèn)編碼機(jī)制。

          該解碼器處理非法字符串有兩種可能的方法。一種方法是不管該非法字符,另一種方法是拋出 IllegalArgumentException 異常。解碼器具體采用哪種方法取決于實(shí)現(xiàn)。


          現(xiàn)在的問(wèn)題是:服務(wù)器返回字符到頁(yè)面,頁(yè)面又調(diào)用js,這個(gè)時(shí)候肯定要轉(zhuǎn)義下,這是相對(duì)比較簡(jiǎn)單的需求。
          服務(wù)器只需借助于apache commons包里的StringEscapeUtils類,在struts2里其實(shí)已經(jīng)集成在xwrok包。
          StringEscapeUtils.escapeJavaScript(returnString);
          這樣就可以搞定這個(gè)問(wèn)題。
          另外也可以用js去處理這個(gè)問(wèn)題,不過(guò)沒(méi)有實(shí)踐,主要是自己js水平有點(diǎn)差,
          escapeJavaScript對(duì)應(yīng)的源碼如下:

          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去實(shí)現(xiàn)也是一樣的,網(wǎng)上也有類似的js代碼。

          出現(xiàn)的問(wèn)題描述:服務(wù)器返了string,經(jīng)過(guò)escapeJavaScript處理后到j(luò)s代碼,js代碼又要用這些string去輸出html.比如img的src為js處理后的字符串,
          最后經(jīng)過(guò)測(cè)試得出以上語(yǔ)句去處理這些問(wèn)題:
          string=encodeURIComponent(string).replace(/@/g,'%40').replace(/'/g,"'").replace(/"/g,'"');
          轉(zhuǎn)化@是為了獲取服務(wù)器資源,比如圖片地址,可以正常輸出。其實(shí)輸出時(shí)后面的轉(zhuǎn)化單引號(hào)和雙引號(hào)是為了保險(xiǎn)起見(jiàn)。比如<img src='*****.jpg'/>這時(shí)就只需要轉(zhuǎn)化單引號(hào)就可以了,這里主要是針對(duì)圖片的處理來(lái)做的,@在其它地方有沒(méi)有必要轉(zhuǎn)化沒(méi)有測(cè)試,如果要顯示圖片,得轉(zhuǎn)化。

          出現(xiàn)的問(wèn)題描述:帶特殊字符串的圖片名要正常顯示出來(lái),得轉(zhuǎn)化下:比如要顯示文件名為:~!@#¥%……&*()——+.jpg的圖片,代碼如下:
          java.net.URLEncoder.encode(photoName,"utf-8")).replace("+", "%20"),轉(zhuǎn)化時(shí)因?yàn)閁RLEncoder把空格轉(zhuǎn)化成了+,所以最后得把+替換回去,20是十六進(jìn)制的,相當(dāng)于十進(jìn)制的32,即對(duì)應(yīng)為空格。
          經(jīng)過(guò)轉(zhuǎn)化后,圖片帶特殊字符就能正常顯示。



          天蒼蒼,野茫茫,風(fēng)吹草底見(jiàn)牛羊

          posts - 80, comments - 24, trackbacks - 0, articles - 32

          Copyright © asdtiang

          asdtiang的博客 PaidMailz
          點(diǎn)擊廣告網(wǎng)賺A(每天4個(gè)廣告,每個(gè)0.0025美元,一個(gè)搜索廣告0.03美元)
          主站蜘蛛池模板: 高州市| 黄骅市| 女性| 巴林左旗| 武平县| 承德县| 富宁县| 于田县| 平和县| 洛阳市| 大关县| 环江| 偏关县| 洪泽县| 廉江市| 上饶县| 宜宾县| 东明县| 长葛市| 沛县| 安新县| 贵德县| 资中县| 永康市| 霍邱县| 麦盖提县| 仁化县| 合肥市| 绥阳县| 襄城县| 景洪市| 江都市| 乐业县| 岳阳市| 漾濞| 东乌| 永泰县| 宜丰县| 上犹县| 眉山市| 竹北市|