Máy chủ.UrlEncode so với HttpUtility.UrlEncode


177

Có sự khác biệt giữa Server.UrlEncode và HttpUtility.UrlEncode không?

Câu trả lời:


133

HttpServerUtility.UrlEncodesẽ sử dụng HttpUtility.UrlEncodenội bộ. Không có sự khác biệt cụ thể. Lý do cho sự tồn tại của Server.UrlEncodelà khả năng tương thích với ASP cổ điển.


3
Đối với những gì được thoát. Trong nội bộ, nó gọi chức năng này là Referenceource.microsoft.com/#System/net/System/Net/iêu
Jeff

Dành cho độc giả: Vui lòng xem câu trả lời của Joel Muller bên dưới. Đó là cách hiệu quả nhất để mã hóa URL: stackoverflow.com/a/603962/190476
Sudhanshu Mishra

264

Tôi đã bị đau đầu đáng kể với các phương pháp này trước đây, tôi khuyên bạn nên tránh mọi biến thể của UrlEncode, và thay vào đó hãy sử dụngUri.EscapeDataString - ít nhất là một phương pháp có hành vi dễ hiểu.

Hãy xem nào...

HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
                                  //standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
                                        // want, since you still need to
                                        // escape special characters yourself

Nhưng sở thích cá nhân của tôi phải là httpUtility.UrlPathEncode - điều này thực sự không thể hiểu được. Nó mã hóa:

  • "" ==> "% 20"
  • "100% đúng" ==> "100 %% 20true" (ok, url của bạn đã bị hỏng ngay bây giờ)
  • "kiểm tra A.aspx # neo B" ==> "kiểm tra% 20A.aspx # neo% 20B "
  • "test A.aspx? hmm # anchor B" ==> "test% 20A.aspx? hmm #anchor B " ( lưu ý sự khác biệt với chuỗi thoát trước đó! )

Nó cũng có tài liệu MSDN cụ thể đáng yêu "Mã hóa phần đường dẫn của chuỗi URL để truyền HTTP đáng tin cậy từ máy chủ Web đến máy khách." - mà không thực sự giải thích những gì nó làm. Bạn ít có khả năng tự bắn vào chân mình bằng một khẩu Uzi ...

Nói tóm lại, hãy bám lấy Uri.EscapeDataString .


4
Và thật không may, nó vẫn không hoạt động khi thực hiện các yêu cầu HTTP đối với một số máy chủ web - Uri.EscapeDataString () không mã hóa "!" hoặc "'", khác với cách mà hầu hết các trình duyệt thoát () của trình duyệt hoạt động ...
Chris R. Donnelly

6
! và 'ký tự không được mã hóa; nhưng nếu một máy chủ web lỗi yêu cầu điều này, thật dễ dàng để giải quyết. Tránh chức năng thoát của javascript - vốn dĩ đã có lỗi (không thể làm tròn số đối với một). Xem xkr.us/articles/javascript/encode-compare - nhưng tóm lại; thay vào đó, bạn có thể sử dụng encodeUriComponent (), hoạt động tương tự như EscapeDataString - nó có thể dự đoán và đảo ngược mã hóa một chuỗi, và cũng không mã hóa! và 'ký tự.
Eamon Nerbonne

2
Điều này đã cũ, nhưng câu hỏi đã được đặt ở trang đầu, vì vậy .... Phần đường dẫn của chuỗi url là phần giữa tên miền và? hoặc # trong một url.
Powerlord

2
@Tim: có thể có một vài ?người và ai sẽ nói cái nào được mã hóa và cái nào dùng làm dấu phân cách? Về không gian: trong cả hai trường hợp, khoảng trắng nằm trong hàm băm, do đó, sự hiện diện hay vắng mặt của một đoạn truy vấn không quan trọng. Và cuối cùng, không thể tha thứ cho một Uri như trong ví dụ thứ hai chứa%. Các UrlPathEncodephương pháp được đơn giản borked và không bao giờ nên được sử dụng.
Eamon Nerbonne

1
Tôi nghĩ rằng câu trả lời của tôi tại stackoverflow.com/a/13993486/237091 có thể làm sáng tỏ một chút về việc sử dụng UrlEncode / UrlPathEncode.
Scott Stafford

60

Chuyển tiếp nhanh gần 9 năm kể từ lần đầu tiên được hỏi và trong thế giới của .NET Core và .NET Standard, có vẻ như các tùy chọn phổ biến nhất chúng tôi có để mã hóa URL là WebUtility.UrlEncode (bên dướiSystem.Net ) và Uri.EscapeDataString . Đánh giá bằng câu trả lời phổ biến nhất ở đây và ở nơi khác, Uri.EscapeDataString dường như được ưa thích hơn. Nhưng nó là? Tôi đã thực hiện một số phân tích để hiểu sự khác biệt và đây là những gì tôi nghĩ ra:

Đối với mục đích mã hóa URL, các ký tự phù hợp với một trong 3 loại: không được giám sát (hợp pháp trong một URL); dành riêng (hợp pháp trong nhưng có ý nghĩa đặc biệt, vì vậy bạn có thể muốn mã hóa nó); và mọi thứ khác (phải luôn được mã hóa).

Theo RFC , các ký tự dành riêng là::/?#[]@!$&'()*+,;=

Và các ký tự không được giám sát là chữ và số -._~

Lời phán quyết

Uri.EscapeDataString xác định rõ nhiệm vụ của mình:% -encode tất cả các ký tự được bảo lưu và bất hợp pháp. WebUtility.UrlEncode mơ hồ hơn trong cả định nghĩa và triển khai. Điều kỳ lạ là, nó mã hóa một số ký tự dành riêng nhưng không phải là ký tự khác (tại sao dấu ngoặc đơn và không phải dấu ngoặc ??), và người lạ vẫn mã hóa nó một cách vô tư~ ký tự .

Do đó, tôi đồng tình với lời khuyên phổ biến - sử dụng Uri.EscapeDataString khi có thể và hiểu rằng các ký tự dành riêng như /?sẽ được mã hóa. Nếu bạn cần xử lý các chuỗi có khả năng lớn, đặc biệt là với nội dung biểu mẫu được mã hóa URL, bạn sẽ cần phải quay lại WebUtility.UrlEncode và chấp nhận các yêu cầu của nó hoặc giải quyết vấn đề khác.


EDIT: Tôi đã cố gắng để khắc phục TẤT CẢ những khuyết tật nêu trên trong Flurl qua Url.Encode, Url.EncodeIllegalCharactersUrl.Decodephương pháp tĩnh. Các gói này nằm trong gói lõi (rất nhỏ và không bao gồm tất cả nội dung HTTP) hoặc thoải mái trích xuất chúng từ nguồn. Tôi hoan nghênh bất kỳ ý kiến ​​/ phản hồi bạn có về những điều này.


Đây là mã tôi đã sử dụng để khám phá các ký tự được mã hóa khác nhau:

var diffs =
    from i in Enumerable.Range(0, char.MaxValue + 1)
    let c = (char)i
    where !char.IsHighSurrogate(c)
    let diff = new {
        Original = c,
        UrlEncode = WebUtility.UrlEncode(c.ToString()),
        EscapeDataString = Uri.EscapeDataString(c.ToString()),
    }
    where diff.UrlEncode != diff.EscapeDataString
    select diff;

foreach (var diff in diffs)
    Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");

2
Thật là tuyệt vời!
Jorge Aguirre

1
Công việc tuyệt vời xác minh giải pháp được đề xuất trên khung .net hiện đại.
Neowizard

Cần phải đề cập rằng có một số khác biệt giữa WebUtilityHttpUtility . WebUtility đang sử dụng chữ hoa và HttpUtility đang sử dụng chữ thường cho các thực thể hexa. Ngoài ra, httpUtility không được bao gồm trong các phiên bản tập hợp con cũ của .NET Framework "Hồ sơ khách hàng". WebUtility có sẵn từ .NET Framework 4.0.
tibx

28

Hãy nhớ rằng bạn có thể không nên sử dụng một trong những phương pháp đó. Thư viện kịch bản trang web chống chéo của Microsoft bao gồm các thay thế HttpUtility.UrlEncodeHttpUtility.HtmlEncodecả hai đều tuân thủ tiêu chuẩn hơn và an toàn hơn. Như một phần thưởng, bạn cũng có được một JavaScriptEncodephương pháp.


Sau khi đọc tài liệu và Câu hỏi thường gặp về liên kết được cung cấp, tôi tin rằng câu trả lời này là cách tốt nhất và an toàn nhất để mã hóa dữ liệu! Cảm ơn rất nhiều vì đã chia sẻ điều này!
Sudhanshu Mishra

Liên kết không hoạt động nữa. Các phương pháp thay thế là gì?
Edward Brey

@EdwardBrey Đây là phiên bản mới nhất của thư viện kịch bản trang web Anti-Cross: microsoft.com/en-au/doad/details.aspx?id=28589
Sudhanshu Mishra

11

Server.UrlEncode () có mặt để cung cấp khả năng tương thích ngược với Classic ASP,

Server.UrlEncode(str);

Tương đương với:

HttpUtility.UrlEncode(str, Response.ContentEncoding);

5

Giống nhau, Server.UrlEncode()gọiHttpUtility.UrlEncode()

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.