1. 程式人生 > 實用技巧 >JS——URI編碼和解碼

JS——URI編碼和解碼

需求:當我們傳輸或者儲存含有中文的字串到某些地方時可能會出現字串亂碼或未可知問題的情況,所以在最小改動的情況下解決問題

場景:向Cookie中儲存中文是不建議的

技術:使用JS提供的encodeURIComponent() 函式可把字串作為 URI 元件進行編碼

   使用JS提供的decodeURIComponent() 函式可把字串作為 URI 元件進行解碼

   兩者使用的是UTF-8字符集

實現:

案例如下

<script>
    var afterEncode =  encodeURIComponent("中國,五千年文化古國!");
    console.log(afterEncode);
    
var afterDecode = decodeURIComponent(afterEncode); console.log(afterDecode); </script>

執行結果

技術說明:

以下內容摘自:CSDN

encodeURI 、encodeURIComponent 以及中文亂碼問題

關於前端

encodeURIComponent(), 對文字框的輸入值進行編碼,特殊字元編碼結果是%加上這些符號的ASCII碼十六進位制對照表。

encodeURI() 將整個url編碼,但不會對如下字元進行編碼@#$&=.:/;?+,這些符號的基本上就是http URL中的特殊符號,是不進行編碼的。

@
# 網頁中的一個位置
:/.?=& 大多數URL基本都包含了的符號 http://www.a.com/a?a=b&c=d
+
$

兩種方式的關係及區別:

  1. 無論上述哪一種,都不會對[a-zA-Z0-9]的字元以及! * ( ) '.進行編碼,即編碼之後還是本身。
  2. 這兩種編碼方式對中文的編碼結果是一致的。
  3. encodeURL()不會進行編碼的字元,基本都是httpURL中的預留符號。所以,encodeURIComponent()是一定會去對這些符號進行編碼的,以免對URL造成干擾。

一些常用的編碼結果:(底色部分是encodeURL不編碼的字元)

原值encodeURIComponent

encodeURI

% %25 %25
空格 %20

%20

& %26 &
= %3D =
/ %2F /
@ %40 @
; %3B ;
$ %24 $
: %3A :
+ %2B +
%3F ?
# %23 #
中文 %E4%B8%AD%E6%96%87 %E4%B8%AD%E6%96%87

關於後端:

前端傳值有2種方式,GET和POST。

一、POST方式傳值中文不會產生亂碼問題

  1. JSP 頁面有pageEncoding="UTF-8",進行編碼設定;
  2. web.xml中的 filter 會進行字元編碼設定,進行request.setCharacterEncoding("utf-8")操作。

二、GET方式

1. 亂碼的產生和解決

大多數的中文亂碼是通過GET方式產生的,只因GET方式有自動解碼操作。相當於執行程式碼:

URLDecoder.decode("%E6%B1%89%E5%AD%97", "編碼方式")

tomcat的配置檔案server.xml中,如果不配置解碼方式,就會按照預設的ISO-8859-1編碼進行解碼。具體參照tomcat的文件。

URIEncoding:This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

即服務端就會預設執行 URLDecoder.decode("%E6%B1%89%E5%AD%97", "ISO-8859-1"),即UTF-8編碼,ISO解碼,就會出現亂碼。其中,%E6%B1%89%E5%AD%97 是前端 encodeURI("漢字") 的結果,此函式使用UTF-8編碼。

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

所以,應該在這裡增加 URIEncoding="UTF-8" 的配置,避免亂碼。

2.亂碼時的問號?

前端處理漢字時用的encodeURI是按照UTF-8方式進行編碼,而此種編碼方式是一個漢字佔3位元組。

而通過request取到的引數預設是通過ISO-8859-1的方式進行解碼,找到就顯示?了,並且是3倍於漢字的個數。

3.通過兩次 encodeURI 也可以解決亂碼問題

a . 將“漢字”通過encodeURI或者 encodeURIComponent 編碼一次,會得到字串 %E6%B1%89%E5%AD%97(6位元組),此字串使用UTF-8編碼的,如果此時用ISO-8859-1解碼,在ISO-8859-1的編碼表中找不到“E6”等欄位對應的字元,所以是6個問號。
b . 第二次編碼時,相當於對非中文字元 %E6%B1%89%E5%AD%97 進行編碼,此時服務端無論用哪種解碼方式,都將得到 %E6%B1%89%E5%AD%97 字元,可以正確還原 。
c .這樣,再通過UTF-8 解碼該字元,就可以得到“漢字”了。
即執行 URLDecoder.decode("%E6%B1%89%E5%AD%97", "UTF-8") 方法。