Tôi nên sử dụng encodeURI hoặc encodeURIComponent để mã hóa URL?


279

Nên sử dụng phương pháp nào trong hai phương pháp này để mã hóa URL?



13
Một điểm khác biệt chính là encodeURIsẽ không mã hóa /nên: encodeURIComponent("ac/dc")=> ac%2FdcencodeURI("ac/dc")=>ac/dc

Điều này có thể hữu ích: "encodeURIComponent() and encodeURI() encode a URI by replacing URL reserved characters with their UTF-8 encoding....They differ because encodeURI does not encode queryString or hash values...URLs do not allow many special characters, like spaces or slashes. However these special characters are part of life, so URL encoding was invented." Nguồn
user1063287

Cũng xem phần cụ thể có tiêu đề encodeURIComponent differs from encodeURI as followstại: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Kẻ

Câu trả lời:


321

Nó phụ thuộc vào những gì bạn thực sự muốn làm.

encodeURI giả định rằng đầu vào là một URI hoàn chỉnh có thể có một số ký tự cần mã hóa trong đó.

encodeURIComponent sẽ mã hóa mọi thứ với ý nghĩa đặc biệt, vì vậy bạn sử dụng nó cho các thành phần của URI như

var world = "A string with symbols & characters that have special meaning?";
var uri = 'http://example.com/foo?hello=' + encodeURIComponent(world);

107

Nếu bạn đang mã hóa một chuỗi để đặt thành phần URL (tham số chuỗi truy vấn), bạn nên gọi encodeURIComponent.

Nếu bạn đang mã hóa một URL hiện có, hãy gọi encodeURI.


1
Nếu tôi đang sử dụng ajax, làm thế nào để tôi giải mã url được truyền cho php?
Aditya Shukla

6
Bạn không. Máy chủ web tự động làm điều đó.
Quentin

@Aditya: Nó phụ thuộc vào những gì bạn đang làm.
SLaks

@slaks. Tôi đang truyền tham số qua get nên tôi muốn truy xuất chúng trong php.
Aditya Shukla

2
Tốt. Tôi có thể đã nói hơi vội vàng khi tôi nói rằng máy chủ web sẽ làm điều đó, nhưng bất kỳ thư viện nào bạn sử dụng để đọc dữ liệu biểu mẫu của bạn sẽ chăm sóc nó cho bạn.
Quentin

46

xkr.us có một cuộc thảo luận tuyệt vời, với các ví dụ. Để trích dẫn tóm tắt của họ:

Phương thức esc () không mã hóa ký tự + được hiểu là khoảng trắng ở phía máy chủ cũng như được tạo bởi các biểu mẫu có khoảng trắng trong trường của chúng. Do thiếu sót này và thực tế là chức năng này không xử lý chính xác các ký tự không phải ASCII, bạn nên tránh sử dụng esc () bất cứ khi nào có thể. Sự thay thế tốt nhất thường là encodeURIComponent ().

esc () sẽ không mã hóa: @ * / +

Việc sử dụng phương thức encodeURI () chuyên sâu hơn một chút so với esc () ở chỗ nó mã hóa cho các URI trái ngược với chuỗi truy vấn, là một phần của URL. Sử dụng phương pháp này khi bạn cần mã hóa một chuỗi được sử dụng cho bất kỳ tài nguyên nào sử dụng URI và cần một số ký tự nhất định để không được mã hóa. Lưu ý rằng phương thức này không mã hóa ký tự ', vì nó là ký tự hợp lệ trong các URI.

encodeURI () sẽ không mã hóa: ~! @ # $ & * () =: /,;? + '

Cuối cùng, nên sử dụng phương thức encodeURIComponent () trong hầu hết các trường hợp khi mã hóa một thành phần duy nhất của URI. Phương pháp này sẽ mã hóa các ký tự nhất định thường được công nhận là các ký tự đặc biệt cho các URI để có thể bao gồm nhiều thành phần. Lưu ý rằng phương thức này không mã hóa ký tự ', vì nó là ký tự hợp lệ trong các URI.

encodeURIComponent () sẽ không mã hóa: ~! * () '


Gần đây mới học. Máy chủ TOMCAT 9 đặc biệt hơn về những gì bạn có thể gửi tới URL. encodeURIComponent () dường như hoạt động tốt hơn trong trường hợp bạn có "khoảng trắng" trong những gì bạn cần mã hóa. Tomcat 8 không quan tâm nhưng 9 thì đặc biệt hơn.
Aggie Jon của 87

Vì vậy, nói cách khác là encodeURIthất bại nếu bạn đang cố gắng chuyển đổi tên tệp thành URL và tên tệp có #trong đó
gman

17

Dưới đây là một bản tóm tắt.

  1. esc () sẽ không mã hóa @ * _ + -. /

    Đừng sử dụng nó.

  2. encodeURI () sẽ không mã hóa AZ az 0-9; , /? : @ & = + $ - _. ! ~ * '() #

    Sử dụng nó khi đầu vào của bạn là một URL hoàn chỉnh như ' https://searchexample.com/search?q=wiki '

  3. encodeURIComponent () sẽ không mã hóa AZ az 0-9 - _. ! ~ * '() Sử dụng nó khi đầu vào của bạn là một phần của một URL hoàn chỉnh, vd const queryStr = encodeURIComponent(someString)

1
Đây là một câu trả lời tuyệt vời vì nó nói chính xác những gì họ làm. Tuy nhiên tôi vẫn có một câu hỏi về việc tôi nên sử dụng và khi nào. Điều gì xảy ra nếu thành phần URI của tôi là một URL hoàn chỉnh? Sau đó tôi nên sử dụng Quy tắc 2 hoặc Quy tắc 3 từ phía trên HOẶC có lẽ cả hai như encodeURIComponent (encodeURI (theCompleteURI))
Panu Logic

10

encodeURIComponent (): giả sử rằng đối số của nó là một phần (chẳng hạn như giao thức, tên máy chủ, đường dẫn hoặc chuỗi truy vấn) của một URI. Do đó, nó thoát khỏi các ký tự dấu chấm câu được sử dụng để phân tách các phần của một URI.

encodeURI (): được sử dụng để mã hóa url hiện có


7

Sự khác biệt giữa encodeURIencodeURIComponent:

encodeURIComponent(value)chủ yếu được sử dụng để mã hóa các giá trị tham số queryString và nó mã hóa mọi ký tự áp dụng trong value. encodeURIbỏ qua tiền tố giao thức ( http://) và tên miền.


Trong các trường hợp rất, rất hiếm, khi bạn muốn triển khai mã hóa thủ công để mã hóa các ký tự bổ sung (mặc dù chúng không cần phải được mã hóa trong các trường hợp điển hình) như : ! *, thì bạn có thể sử dụng:

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

( nguồn )


6
Bạn không nên thoát những charachters trong url.
Arashsoft

Như tài liệu được trích dẫn nói: "những ký tự này không có cách sử dụng phân định URI chính thức"
caesarsol

@caesarsol vì vậy, tôi nên chỉnh sửa câu trả lời của mình. hãy cho tôi biết suy nghĩ của bạn bởi vì tôi không thể hiểu tài liệu được trích dẫn đó có nghĩa là gì ..
T.Todua

Nó chỉ vô dụng để mã hóa các ký tự này, trừ khi bạn đang làm gì đó trong các trường hợp sử dụng mã hóa URL thông thường :)
caesarsol

2

Các câu trả lời khác mô tả các mục đích. Dưới đây là các ký tự mà mỗi chức năng sẽ thực sự chuyển đổi :

control = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
        + '\x10\x11\x12\x13\x14\X15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'
                                                                    + '\x7F'
encodeURI         (control + ' "%<>[\\]^`{|}'                             )
encodeURIComponent(control + ' "%<>[\\]^`{|}' + '#$&,:;=?' + '+/@'        )
escape            (control + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

Tất cả các ký tự ở trên được chuyển đổi thành mã thập lục phân phần trăm. Không gian để %20, phần trăm đến %25, vv Các ký tự bên dưới đi qua không thay đổi.

Dưới đây là các ký tự mà các hàm sẽ KHÔNG chuyển đổi :

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

encodeURI         (pass_thru + '#$&,:;=?' + '+/@' + "!'()~")
encodeURIComponent(pass_thru +                      "!'()~")
escape            (pass_thru +              '+/@'          )

-4

Là một quy tắc sử dụng chung encodeURIComponent. Đừng sợ tên dài nghĩ rằng nó cụ thể hơn trong việc sử dụng, với tôi đó là phương pháp được sử dụng phổ biến hơn. Cũng đừng bị cuốn hút vào việc sử dụng encodeURI vì bạn đã kiểm tra nó và nó dường như được mã hóa đúng cách, nó có thể không phải là ý bạn sử dụng và mặc dù thử nghiệm đơn giản của bạn sử dụng "Fred" trong trường tên đầu tiên đã hoạt động, bạn sẽ thấy sau này khi bạn sử dụng văn bản nâng cao hơn như thêm ký hiệu hoặc hashtag thì nó sẽ thất bại. Bạn có thể nhìn vào các câu trả lời khác cho lý do tại sao điều này là.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.