簡體   English   中英

在 JavaScript 中對 utf-8 字符串使用 encodeURI() 與 escape()

[英]Using encodeURI() vs. escape() for utf-8 strings in JavaScript

我在 JavaScript 中處理 utf-8 字符串,需要對它們進行轉義。

escape() / unescape() 和 encodeURI() / decodeURI() 都在我的瀏覽器中工作。

逃脫()

> var hello = "안녕하세요"
> var hello_escaped = escape(hello)
> hello_escaped
  "%uC548%uB155%uD558%uC138%uC694"
> var hello_unescaped = unescape(hello_escaped)
> hello_unescaped
  "안녕하세요"

編碼URI()

> var hello = "안녕하세요"    
> var hello_encoded = encodeURI(hello)
> hello_encoded
  "%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94"
> var hello_decoded = decodeURI(hello_encoded)
> hello_decoded
  "안녕하세요"

但是, Mozilla 表示不推薦使用 escape()

盡管 encodeURI() 和 decodeURI() 使用上述 utf-8 字符串,但文檔(以及函數名稱本身)告訴我這些方法用於 URI; 我沒有看到任何地方提到的 utf-8 字符串。

簡單地說,utf-8 字符串可以使用 encodeURI() 和 decodeURI() 嗎?

你好!

當談到escapeunescape ,我遵循兩條規則:

  1. 盡可能避免它們。
  2. 否則,請使用它們。

當您可以輕松地避免它們時:

正如問題中提到的, escapeunescape都已被棄用。 一般來說,應該避免使用不推薦使用的函數。

所以,如果encodeURIComponentencodeURI對你有用,你應該使用它而不是escape

當您無法輕松避免它們時使用它們:

瀏覽器將盡可能努力實現向后兼容。 所有主流瀏覽器都已經實現了escapeunescape 他們為什么要取消實施它們?

如果新規范要求瀏覽器重新定義escapeunescape ,他們將不得不這樣做。 可是等等! 編寫規范的人非常聰明。 他們也有興趣不破壞向后兼容性!

我意識到上述論點是薄弱的。 但是請相信我,......當涉及到瀏覽器時,不推薦使用的東西是有效的。 這甚至包括不推薦使用的 HTML 標簽,例如<xmp><center>

使用escapeunescape

那么自然地,下一個問題是,什么時候使用escapeunescape

最近,在處理CloudBrave 時,我不得不處理utf8latin1和相互轉換。

在閱讀了一堆博客文章后,我意識到這是多么簡單:

var utf8_to_latin1 = function (s) {
    return unescape(encodeURIComponent(s));
};
var latin1_to_utf8 = function (s) {
    return decodeURIComponent(escape(s));
};

這些不使用escapeunescape相互轉換相當復雜。 通過不避免escapeunescape ,生活變得更簡單。

希望這可以幫助。

Mozilla 說不推薦使用 escape() 。

是的,你應該避免同時使用escape()unescape()


簡單地說,utf-8 字符串可以使用 encodeURI() 和 decodeURI() 嗎?

是的,但根據您輸入的形式和所需的輸出形式,您可能需要一些額外的工作。

根據您的問題,我假設您有一個 JavaScript 字符串,並且您想將編碼轉換為 UTF-8,並最終以某種轉義形式存儲該字符串。

首先需要注意的是,JavaScript 字符串編碼是 UCS-2,類似於 UTF-16,不同於 UTF-8。

請參閱: https : //mathiasbynens.be/notes/javascript-encoding

encodeURIComponent()非常適合這項工作,因為它將 UCS-2 JavaScript 字符串轉換為 UTF-8,並以%nn子字符串序列的形式對其進行轉義,其中每個nn是每個字節的兩個十六進制數字。

但是encodeURIComponent()不會轉義 ASCII 范圍內的字母、數字和其他一些字符。 但這很容易解決。

例如,如果要將 JavaScript 字符串轉換為表示原始字符串 UTF-8 編碼的字節的數字數組,則可以使用此函數:

//
// Convert JavaScript UCS2 string to array of bytes representing the string UTF8 encoded
//

function StringUTF8AsBytesArrayFromString( s )
{
    var i,
        n,
        u;

    u = [];
    s = encodeURIComponent( s );

    n = s.length;
    for( i = 0; i < n; i++ )
    {
        if( s.charAt( i ) == '%' )
        {
            u.push( parseInt( s.substring( i + 1, i + 3 ), 16 ) );
            i += 2;
        }
        else
        {
            u.push( s.charCodeAt( i ) );
        }
    }

    return u;
}

如果要將字符串轉換為十六進制表示:

//
// Convert JavaScript UCS2 string to hex string representing the bytes of the string UTF8 encoded
//

function StringUTF8AsHexFromString( s )
{
    var u,
        i,
        n,
        s;

    u = StringUTF8AsBytesArrayFromString( s );
    n = u.length;
    s = '';    

    for( i = 0; i < n; i++ )
    {
        s += ( u[ i ] < 16 ? '0' : '' ) + u[ i ].toString( 16 );
    }

    return s;
}

如果將 for 循環中的行更改為

s += '%' + ( u[ i ] < 16 ? '0' : '' ) + u[ i ].toString( 16 );

(在每個十六進制數字前添加%符號)

可以使用decodeURIComponent()將生成的轉義字符串(UTF-8 編碼)轉回 JavaScript UCS-2 字符串

永遠不能使用encodeURI()encodeURIComponent() 讓我們試試看:

 console.log(encodeURIComponent('@#*'));

輸入: @#* 輸出: %40%23* 等等,那么, *字符到底發生了什么? 怎么沒轉化? 想象一下:您詢問用戶要刪除哪個文件,他們的回答是* 服務器端,您使用encodeURIComponent()轉換它,然后運行rm * 好吧,有消息告訴您:使用encodeURIComponent()意味着您剛剛刪除了所有文件。

使用fixedEncodeURI() ,當嘗試編碼完整的 URL(即所有example.com?arg=val )時,如MDN encodeURI() 文檔中定義和進一步解釋的那樣......

 function fixedEncodeURI(str) { return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']'); }

或者,您可能需要使用fixedEncodeURIComponent() ,當嘗試編碼 URL 的一部分(即example.com?arg=valargval )時,如MDN encodeURIComponent() 文檔中定義和進一步解釋的那樣...

 function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }

如果根據上面的描述你無法區分它們,我總是喜歡將其簡化為:

  • fixedEncodeURI()不會將+@?=:#;,$&編碼為其 http 編碼的等價物(因為&+是常見的 URL 運算符)
  • fixedEncodeURIComponent()會將+@?=:#;,$&編碼為它們的 http 編碼等價物。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM