﻿# 詳細解說幾個建置網站時常用的編碼方法

每次有新的開發人員進公司，在開發網站的時候幾乎都會遇到「不知道應該在**什麼時候**要選用**什麼編碼**的狀況」，大部分的初學者甚至根本不知道何謂編碼(Encode)，而我也面試過好幾位在業界工作多年的工程師，有些也無法精確說明應該在**什麼時候**要選用**什麼編碼**，甚至有人說「編碼做什麼？我沒編碼也沒發生過錯誤啊！」。所以我想有必要特別寫一篇文章詳述各種常用的編碼方法與使用情境。

**為什麼要編碼？**

為了讓資料能夠在網路上正確傳遞，我們通常會把 Binary 格式的資料先轉成 Text 格式再傳遞資料，而這種轉換的過程就是「編碼(Encode)」，反之就是「解碼(Decode)」。除此之外，我們也會將某些 "文字" 進行編碼，讓原本非 ASCII 的文字能夠以 ASCII 的字元傳遞，這樣做是為了避免文字在網路傳遞的時候會失真，而這種讓非 ASCII 的文字轉換成以 ASCII 的字元的表達方式也通稱做「編碼(Encode)」。

這些不清楚何謂編碼的開發人員所開發出來的程式最容易遭受知名的 [Cross-Site Scripting](http://en.wikipedia.org/wiki/Cross-site_scripting) (XSS) 攻擊，所以不得不注意。

**編碼的種類有幾種？**

編碼方法百百種，例如 UrlEncode, HtmlEncode, [Base64](http://en.wikipedia.org/wiki/Base64)Encode, [Quoted-Printable](http://en.wikipedia.org/wiki/Quoted_printable) Encode, [UUEncode](http://en.wikipedia.org/wiki/Uuencode), ...... 太多了，但是對網頁開發人員來說最常用的莫過於 UrlEncode 與 HtmlEncode 了，不過，光是這兩種常見的編碼還可以再區分成幾種不同的編碼方式喔，這就是一般人不會深入瞭解的部分，我將針對 .NET 與 JavaScript 中常用的方法(method)與函數(function)進行實例解說。

**.NET 相關的 UrlEncode 與 HtmlEncode 方法**

-   [HttpUtility.UrlEncode](http://msdn.microsoft.com/zh-tw/library/4fkewx0t\(VS.80\).aspx)  
    URL 編碼方式會將 URL 中不允許的字元轉換為相等的字元實體。
-   [HttpUtility.UrlDecode](http://msdn.microsoft.com/zh-tw/library/adwtk1fy\(VS.80\).aspx)  
    剛好是 UrlEncode 的相反，將透過 UrlEncode 過的字串解碼成原本的字串。
-   [HttpUtility.UrlEncodeUnicode](http://msdn.microsoft.com/zh-tw/library/system.web.httputility.urlencodeunicode\(VS.80\).aspx)  
    等於 JavaScript 的 escape() 方法，用 %uXXXX 的方式表達。
-   [HttpUtility.UrlPathEncode](http://msdn.microsoft.com/zh-tw/library/system.web.httputility.urlpathencode\(VS.80\).aspx)  
    HttpUtility.UrlPathEncode 方法**不會**對下列字元進行編碼：":"、"/"、";"、"?" 以及任何可見的 ASCII 字元都不會被編碼，另外網址中的 QueryString (網址中 ? 之後的所有字元) 也都不會被編碼。  
    這方法通常用於對網址中「目錄名稱」與「檔名」編碼！
-   [HttpUtility.HtmlEncode](http://msdn.microsoft.com/zh-tw/library/73z22y6h\(VS.80\).aspx)  
    將 HTML 文件中不允許出現的字元進行編碼，通常會編碼 "<"、">"、"&" 等字元。
-   [HttpUtility.HtmlAttributeEncode](http://msdn.microsoft.com/zh-tw/library/wdek0zbf\(VS.80\).aspx)  
    只會將引號 (")、連字號 (&) 和左角括弧 (<) 轉換成對等的字元實體。  
    它的速度比 HtmlEncode 方法快許多。  
    HtmlAttributeEncode 方法所產生的字串，僅可用於雙引號括住的屬性 (Attribute)。  
    將 HtmlAttributeEncode 方法與單引號括住的屬性搭配使用時，可能會發生安全性問題。
-   [HttpUtility.HtmlDecode](http://msdn.microsoft.com/zh-tw/library/73z22y6h\(VS.80\).aspx)  
    剛好是 HtmlEncode 的相反，將透過 HtmlEncode 過的字串解碼成原本的字串。

**JavaScript 相關的 UrlEncode 與 HtmlEncode 函數**

-   [escape](http://msdn.microsoft.com/zh-tw/library/z3f12b47\(VS.80\).aspx)  
    會以 Unicode 方式進行編碼，用 %uXXXX 的方式呈現編碼的格式。  
    所有的空格、標點符號、重音字元以及其他非 ASCII 字元均以 %xx 編碼取代，其中的 xx 就等於表示該字元的十六進位數字。  
    值大於 255 的字元，則以 %uxxxx 格式儲存。  
    與 encodeURI、encodeURIComponent 不相容
-   [unescape](http://msdn.microsoft.com/zh-tw/library/a6d6sax2\(VS.80\).aspx)  
    將透過 escape 函數編碼過的字串解碼。
-   [encodeURI](http://msdn.microsoft.com/zh-tw/library/91td9cas\(VS.80\).aspx)  
    encodeURI 方法不會對下列字元進行編碼：":"、"/"、";"、"?"、"="、"&"。  
    這個函數的目的在於將一個現有的網址，對各個不同的片段進行編碼，讓現有的網址更加標準化。
-   [decodeURI](http://msdn.microsoft.com/zh-tw/library/32acfset\(VS.80\).aspx)  
    將透過 encodeURI 函數編碼過的字串解碼。
-   [encodeURIComponent](http://msdn.microsoft.com/zh-tw/library/77tettz4\(v=VS.80\).aspx)  
    這個函數會將所有傳入的字元進行編碼。  
    他把傳入的字串視為「整個 URI 的部分」，例如說你要有個 QueryString 的參數為 a，但其值是 [http://www.example.com/](http://www.example.com/) 的話，你就一定要用 [encodeURIComponent](http://msdn.microsoft.com/zh-tw/library/32acfset\(VS.80\).aspx) 對整個 url 進行編碼！
-   [decodeURIComponent](http://msdn.microsoft.com/zh-tw/library/k6axhxh1\(v=VS.80\).aspx)  
    將透過 decodeURIComponent 函數編碼過的字串解碼。

**相關連結**

-   [淺談在 JavaScript 中的 URLEncode 動作](/post/2007/11/14/Talking-about-JavaScript-URLEncode)
