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,即對應為空格。
經過轉化后,圖片帶特殊字符就能正常顯示。
天蒼蒼,野茫茫,風吹草底見牛羊