Câu hỏi Khi nào bạn phải sử dụng lối thoát thay vì encodeURI / encodeURIComponent?


Khi mã hóa chuỗi truy vấn được gửi tới máy chủ web - khi nào bạn sử dụng escape() và khi nào bạn sử dụng encodeURI() hoặc là encodeURIComponent():

Sử dụng lối thoát:

escape("% +&=");

HOẶC LÀ

sử dụng encodeURI () / encodeURIComponent ()

encodeURI("http://www.google.com?var1=value1&var2=value2");

encodeURIComponent("var1=value1&var2=value2");

1285
2017-09-16 19:24


gốc


Điều đáng chú ý là encodeURIComponent("var1=value1&var2=value2") Là không phải trường hợp sử dụng điển hình. Ví dụ đó sẽ mã hóa = và &, đó có lẽ không phải là những gì đã được dự định! encodeURIComponent thường được áp dụng riêng cho chỉ giá trị trong mỗi cặp giá trị khóa (phần sau mỗi =). - Timothy Shields
bạn có cần phải làm bất cứ điều gì để chìa khóa? Điều gì nếu nó có một = trong nó? (thậm chí có thể không?) - Mala
@Mala Tôi vẫn còn mới với lập trình web nói chung, nhưng những gì tôi đã sử dụng trong kinh nghiệm hạn chế của tôi là mã hóa khóa và giá trị riêng biệt, đảm bảo lưu trú '=': var params = encodeURIComponent(key) + '=' + encodeURIComponent(value);- Có thể người khác biết cách tốt hơn. - nedshares
@nedshares Tôi đã chơi với điều đó, nhưng theo như tôi có thể nói khóa không có vẻ được mã hóa ... ít nhất là không theo cùng một cách. Có lẽ nó chống lại spec để có một = trong khóa? - Mala
Cũng đáng để chỉ ra rằng các triển khai JavaScript gần đây cung cấp các giao diện cấp cao hơn URL và URLSearchParams để thao tác URL và chuỗi truy vấn của họ. - Bart Robinson


Các câu trả lời:


bỏ trốn()

Đừng dùng nó! escape() được định nghĩa trong phần B.2.1.2 thoát và văn bản giới thiệu của Phụ lục B nói:

... Tất cả các tính năng và hành vi ngôn ngữ được chỉ định trong phụ lục này có một hoặc nhiều đặc điểm không mong muốn và trong trường hợp không sử dụng kế thừa sẽ bị xóa khỏi đặc tả này. ...
  ... Các lập trình viên không nên sử dụng hoặc giả định sự tồn tại của các tính năng và hành vi này khi viết mã ECMAScript mới ....

Hành vi:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape

Các ký tự đặc biệt được mã hóa ngoại trừ: @ * _ + -. /

Dạng thập lục phân cho các ký tự, có giá trị đơn vị mã là 0xFF hoặc nhỏ hơn, là một chuỗi thoát hai chữ số: %xx.

Đối với các ký tự có đơn vị mã lớn hơn, định dạng gồm bốn chữ số %uxxxx Được sử dụng. Điều này không được phép trong chuỗi truy vấn (như được định nghĩa trong RFC3986):

query       = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

Dấu phần trăm chỉ được phép nếu nó được theo sau bởi hai chữ số thập lục phân, phần trăm theo sau là u không được phép.

encodeURI ()

Sử dụng encodeURI khi bạn muốn một URL làm việc. Thực hiện cuộc gọi này:

encodeURI("http://www.example.org/a file with spaces.html")

để có được:

http://www.example.org/a%20file%20with%20spaces.html

Đừng gọi encodeURIComponent vì nó sẽ hủy URL và trả về

http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html

encodeURIComponent ()

Sử dụng encodeURIComponent khi bạn muốn mã hóa giá trị của tham số URL.

var p1 = encodeURIComponent("http://example.org/?a=12&b=55")

Sau đó, bạn có thể tạo URL bạn cần:

var url = "http://example.net/?param1=" + p1 + "&param2=99";

Và bạn sẽ nhận được URL hoàn chỉnh này:

http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55&param2=99

Lưu ý rằng encodeURIComponent không thoát khỏi ' tính cách. Một lỗi phổ biến là sử dụng nó để tạo các thuộc tính html như href='MyUrl', có thể bị một lỗi tiêm. Nếu bạn đang xây dựng html từ chuỗi, hãy sử dụng " thay vì ' cho dấu ngoặc kép thuộc tính hoặc thêm lớp mã hóa bổ sung (' có thể được mã hóa dưới dạng% 27).

Để biết thêm thông tin về loại mã hóa này, bạn có thể kiểm tra: http://en.wikipedia.org/wiki/Percent-encoding


1816
2018-05-24 06:54



@Francois, tùy thuộc vào máy chủ nhận, nó có thể không giải mã đúng cách thoát khỏi mã hóa các ký tự ASCII hoặc non-ASCII như thế nào: Ví dụ, lớp FieldStorage của Python sẽ không giải mã chuỗi trên đúng nếu được mã hóa bằng cách thoát. - Ray
@Francois escape () mã hóa các ký tự 128 ASCII thấp hơn ngoại trừ chữ cái, chữ số và *@-_+./ trong khi unescape () là nghịch đảo của escape (). Theo như tôi có thể nói, chúng là các hàm kế thừa được thiết kế để mã hóa URL và chỉ được triển khai để tương thích ngược. Nói chung, chúng không nên được sử dụng trừ khi tương tác với một ứng dụng / dịch vụ web / etc được thiết kế cho chúng. - Anthony DiSanti
Trừ khi tất nhiên bạn đang cố gắng để vượt qua một URL như là một thành phần URI trong đó trường hợp gọi encodeURIComponent. - tom
Tại sao nó không xử lý các báo giá duy nhất? - Eric
@Eric Nó không mã hóa một trích dẫn, bởi vì báo giá đơn là một ký tự hoàn toàn hợp lệ xảy ra trong một URI (RFC-3986). Sự cố xảy ra khi bạn nhúng URI trong HTML, trong đó một dấu nháy đơn là không phải một ký tự hợp lệ. Sau đó, các URI đó cũng phải được "mã hóa HTML" (sẽ thay thế ' với ') trước khi được đưa vào tài liệu HTML. - Lee


Sự khác biệt giữa encodeURI() và encodeURIComponent() chính xác là 11 ký tự được mã hóa bởi encodeURIComponent nhưng không phải bởi encodeURI:

Table with the ten differences between encodeURI and encodeURIComponent

Tôi đã tạo bảng này một cách dễ dàng với console.table trong Google Chrome với mã này:

var arr = [];
for(var i=0;i<256;i++) {
  var char=String.fromCharCode(i);
  if(encodeURI(char)!==encodeURIComponent(char)) {
    arr.push({
      character:char,
      encodeURI:encodeURI(char),
      encodeURIComponent:encodeURIComponent(char)
    });
  }
}
console.table(arr);


391
2017-10-09 09:26



1 cho rõ ràng và một cho magic.table magic! - bladnman
Trình duyệt này có phụ thuộc không? - Pacerier
@bladnman encodeURI và encodeURIComponent nên hoạt động theo cách này trong tất cả các trình duyệt chính. Bạn có thể kiểm tra mã ở trên trong Chrome và Firefox dưới dạng cả support.table. Trong các trình duyệt khác (bao gồm Firefox và Chrome), bạn có thể sử dụng mã sau: var arr=[]; for(var i=0;i<256;i++){var char=String.fromCharCode(i); if(encodeURI(char)!==encodeURIComponent(char)) console.log("character: "+char + " | encodeURI: " +encodeURI(char) + " |encodeURIComponent: " + encodeURIComponent(char) ) } - Johann Echavarria
Ý tôi là @Pacerier :) - Johann Echavarria
TÔI CẦN PHẢI TRẢ LỜI THỜI GIAN NÀY! Thật không may chỉ có thể upvote một lần. - Ramazan Polat


Tôi thấy bài viết này khai sáng: Javascript Madness: Phân tích chuỗi truy vấn

Tôi tìm thấy nó khi tôi đã cố gắng để undersand tại sao decodeURIComponent đã không giải mã '+' một cách chính xác. Đây là một trích xuất:

String:                         "A + B"
Expected Query String Encoding: "A+%2B+B"
escape("A + B") =               "A%20+%20B"     Wrong!
encodeURI("A + B") =            "A%20+%20B"     Wrong!
encodeURIComponent("A + B") =   "A%20%2B%20B"   Acceptable, but strange

Encoded String:                 "A+%2B+B"
Expected Decoding:              "A + B"
unescape("A+%2B+B") =           "A+++B"       Wrong!
decodeURI("A+%2B+B") =          "A+++B"       Wrong!
decodeURIComponent("A+%2B+B") = "A+++B"       Wrong!

43
2018-05-08 07:51



Bài viết bạn liên kết có chứa rất nhiều điều vô nghĩa. Dường như với tôi, bản thân tác giả đã không hiểu những gì các chức năng được sử dụng đúng cách cho ... - Christoph
@Christoph Tất cả đều hợp lý với tôi. Đặc biệt, tôi đồng ý với anh ấy rằng encodeURI có vẻ như nó chỉ hữu ích trong một trường hợp khá mơ hồ và thực sự không cần tồn tại. Tôi có một số khác biệt về ý kiến ​​với anh ta, nhưng tôi không thấy bất cứ điều gì hoàn toàn sai hoặc ngu ngốc trong đó. Chính xác những gì bạn nghĩ là vô nghĩa? - Mark Amery
Các enctype thuộc tính của FORM phần tử xác định loại nội dung được sử dụng để mã hóa tập dữ liệu biểu mẫu để gửi tới máy chủ. ứng dụng / x-www-form-urlencoded    Đây là loại nội dung mặc định. Các biểu mẫu được gửi với loại nội dung này phải được mã hóa như sau: [...] Ký tự khoảng trắng được thay thế bằng `` + 'và [...] Ký tự không phải chữ và số được thay thế bởi `% HH', [...]  Tham khảo: HTML4 Sepc - cychoi
decodeURIComponent ("A +% 2B + B" .replace (/ \ + / g, "")) = "A + B" - Nicholas
encodeURIComponent ('A + B') thay thế (/ \% 20 / g, '+') + '\ n' + decodeURIComponent ("A +% 2B + B" .replace (/ \ + / g, '% 20' )); - Zlatin Zlatev


encodeURIComponent không mã hóa -_.!~*'(), gây ra sự cố khi đăng dữ liệu lên php bằng chuỗi xml.

Ví dụ:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

Thoát chung với encodeURI
%3Cxml%3E%3Ctext%20x=%22100%22%20y=%22150%22%20value=%22It's%20a%20value%20with%20single%20quote%22%20/%3E%20%3C/xml%3E

Bạn có thể thấy, báo giá đơn lẻ không được mã hóa. Để giải quyết vấn đề tôi đã tạo ra hai hàm để giải quyết vấn đề trong dự án của tôi, cho Mã hóa URL:

function encodeData(s:String):String{
    return encodeURIComponent(s).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29");
}

Đối với URL giải mã:

function decodeData(s:String):String{
    try{
        return decodeURIComponent(s.replace(/\%2D/g, "-").replace(/\%5F/g, "_").replace(/\%2E/g, ".").replace(/\%21/g, "!").replace(/\%7E/g, "~").replace(/\%2A/g, "*").replace(/\%27/g, "'").replace(/\%28/g, "(").replace(/\%29/g, ")"));
    }catch (e:Error) {
    }
    return "";
}

37
2017-09-16 19:26



Nó cũng không làm dấu # (pound / hash / number), là% 23. - xr280xr


encodeURI () - hàm escape () là để thoát javascript, không phải HTTP.


36
2017-10-08 15:20



Nếu tôi có một url như thế này: var url = "http://kuler-api.adobe.com/rss/get.cfm?startIndex=0&itemsPerPage=20&timeSpan=0&listType=rating"... Và tôi muốn truy cập nó qua API của Google Ajax, như sau: var gurl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=?&q=" + url;... sau đó tôi phải sử dụng escape(url). encodeURI(url) không hoạt động với các tham số như vậy. - Lance Pollard
bạn nên sử dụng ecnodeURIComponent (url) - Ustaman Sangat
Tất cả 3 chức năng đều có vấn đề. Tốt hơn hết là nên tạo ra chức năng của riêng bạn mà thực hiện công việc. - Jerry Joseph


Bảng so sánh nhỏ Java so với JavaScript so với PHP.

1. Java URLEncoder.encode (using UTF8 charset)
2. JavaScript encodeURIComponent
3. JavaScript escape
4. PHP urlencode
5. PHP rawurlencode

char   JAVA JavaScript --PHP---
[ ]     +    %20  %20  +    %20
[!]     %21  !    %21  %21  %21
[*]     *    *    *    %2A  %2A
[']     %27  '    %27  %27  %27 
[(]     %28  (    %28  %28  %28
[)]     %29  )    %29  %29  %29
[;]     %3B  %3B  %3B  %3B  %3B
[:]     %3A  %3A  %3A  %3A  %3A
[@]     %40  %40  @    %40  %40
[&]     %26  %26  %26  %26  %26
[=]     %3D  %3D  %3D  %3D  %3D
[+]     %2B  %2B  +    %2B  %2B
[$]     %24  %24  %24  %24  %24
[,]     %2C  %2C  %2C  %2C  %2C
[/]     %2F  %2F  /    %2F  %2F
[?]     %3F  %3F  %3F  %3F  %3F
[#]     %23  %23  %23  %23  %23
[[]     %5B  %5B  %5B  %5B  %5B
[]]     %5D  %5D  %5D  %5D  %5D
----------------------------------------
[~]     %7E  ~    %7E  %7E  ~
[-]     -    -    -    -    -
[_]     _    _    _    _    _
[%]     %25  %25  %25  %25  %25
[\]     %5C  %5C  %5C  %5C  %5C
----------------------------------------
char  -JAVA-  --JavaScript--  -----PHP------
[ä]   %C3%A4  %C3%A4  %E4     %C3%A4  %C3%A4
[ф]   %D1%84  %D1%84  %u0444  %D1%84  %D1%84

14
2017-09-16 19:40



Một cái gì đó tương tự ở đây: the-art-of-web.com/javascript/escape - Christophe Roussy
dude. bạn đá để đăng bài này! - williamle8300


Cũng nên nhớ rằng tất cả chúng đều mã hóa các bộ ký tự khác nhau và chọn một bộ bạn cần một cách thích hợp. encodeURI () mã hóa ít ký tự hơn encodeURIComponent (), mã hóa các ký tự ít hơn (và cũng khác nhau, thành điểm của dannyp) so với escape ().


10
2018-04-23 16:54





Tôi khuyên bạn không nên sử dụng một trong những phương pháp như vậy. Viết chức năng của riêng bạn mà làm điều đúng.

MDN đã đưa ra một ví dụ tốt về mã hóa url được hiển thị bên dưới.

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName);

console.log(header); 
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"


function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            //  so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent


9
2018-04-21 07:55



những gì một câu trả lời tuyệt vời (nếu nó tương thích trên chrome cạnh và firefox trong khi không thực hiện bất kỳ sai lầm) - yan bellavance
Câu trả lời này xứng đáng có nhiều upvotes hơn. - Adam


Với mục đích mã hóa javascript đã đưa ra ba hàm sẵn có -

  1. escape () - không mã hóa @*/+ Phương pháp này không được chấp nhận sau ECMA 3 vì vậy cần tránh phương pháp này.

  2. encodeURI () - không mã hóa ~!@#$&*()=:/,;?+' Nó giả định rằng URI là một URI hoàn chỉnh, do đó, không mã hóa các ký tự dành riêng có ý nghĩa đặc biệt trong URI. Phương pháp này được sử dụng khi mục đích là chuyển đổi URL hoàn chỉnh thay vì một số phân đoạn URL đặc biệt. Thí dụ - encodeURI('http://stackoverflow.com'); sẽ cho - http://stackoverflow.com

  3. encodeURIComponent () -does không mã hóa - _ . ! ~ * ' ( ) Hàm này mã hóa thành phần Định danh Tài nguyên Đồng nhất (URI) bằng cách thay thế từng cá thể của một số ký tự nhất định bằng một, hai, ba hoặc bốn chuỗi thoát biểu diễn mã hóa UTF-8 của ký tự. Phương pháp này nên được sử dụng để chuyển đổi thành phần của URL. Ví dụ: một số đầu vào của người dùng cần được thêm vào Thí dụ - encodeURI('http://stackoverflow.com'); sẽ cung cấp cho - http% 3A% 2F% 2Fstackoverflow.com

Tất cả mã hóa này được thực hiện trong UTF 8 nghĩa là các ký tự sẽ được chuyển đổi theo định dạng UTF-8. 

encodeURIComponent khác với encodeURI ở chỗ nó mã hóa các ký tự dành riêng và Số hiệu # của encodeURI


5
2017-08-08 12:34





Tôi đã tìm thấy rằng thử nghiệm với các phương pháp khác nhau là một kiểm tra sanity tốt ngay cả sau khi có một xử lý tốt về những gì khác nhau của họ sử dụng và khả năng được.

Hướng tới mục đích đó tôi đã tìm thấy Trang web này cực kỳ hữu ích để xác nhận những nghi ngờ của tôi rằng tôi đang làm điều gì đó một cách thích hợp. Nó cũng đã được chứng minh hữu ích cho việc giải mã một chuỗi encodeURIComponent'ed mà có thể được khá khó khăn để giải thích. Một dấu trang tuyệt vời để có:

http://www.the-art-of-web.com/javascript/escape/


3
2018-06-21 12:39





Tôi có chức năng này ...

var escapeURIparam = function(url) {
    if (encodeURIComponent) url = encodeURIComponent(url);
    else if (encodeURI) url = encodeURI(url);
    else url = escape(url);
    url = url.replace(/\+/g, '%2B'); // Force the replacement of "+"
    return url;
};

1
2017-09-27 06:56



Thoát không còn được dùng nữa: w3schools.com/jsref/jsref_escape.asp - Christian Vielma
@ChristianVielma escape () bị phản đối nhưng không bao giờ tham khảo w3schools.com. xem w3fools.com - Jerry Joseph
Ồ cảm ơn! Không biết điều đó. - Christian Vielma
@Christian Vielma - Một số tìm thấy tài liệu tham khảo tại W3Schools được ít gây tranh cãi và hữu ích. Không phải ai cũng đồng ý rằng W3Schools không bao giờ nên được tham chiếu. - DavidRR
W3Schools nhận được một rap xấu. Chắc chắn họ không phải luôn luôn chính xác, nhưng sau đó một lần nữa tôi đã đi qua nhiều bài đăng trên blog mà là hoàn toàn sai là tốt. Đối với tôi đôi khi nó là một điểm khởi đầu tuyệt vời chỉ để tìm hiểu một số thuật ngữ và sau đó tôi đi sâu hơn một chút với các nguồn lực khác. Quan trọng nhất là một nguồn tài nguyên không bao giờ nên là kinh thánh khi nói đến loại công cụ này. - ryandlf