2010-07-08 25 views
9

Per MSDNHttpUtility.UrlEncode có khớp với thông số cho 'x-www-form-urlencoded' không?

URLEncode chuyển đổi ký tự như sau:

  • Spaces() được chuyển đổi thành dấu cộng (+).
  • Ký tự không phải chữ và số được thoát theo trình bày thập lục phân của chúng.

Đó là tương tự, nhưng không hoàn toàn giống như W3C

application/x-www-form-urlencoded

Đây là loại nội dung mặc định. Biểu mẫu được gửi với loại nội dung này phải được mã hóa như sau:

  1. Tên và giá trị kiểm soát được thoát. ký tự không gian được thay thế bởi ký tự '+', và sau đó reserved được thoát như mô tả trong RFC1738, mục 2.2: Không tự chữ và số nhân vật được thay thế bằng '% HH', một dấu hiệu phần trăm và hai thập lục phân chữ số đại diện cho Mã ASCII của ký tự. Ngắt dòng là được biểu thị dưới dạng cặp "CR LF" (nghĩa là, '% 0D% 0A').

  2. Tên/giá trị kiểm soát được liệt kê theo thứ tự chúng xuất hiện trong tài liệu . Tên được tách ra từ giá trị bằng '=' và cặp tên/giá trị được phân tách với nhau bằng '&'.

 

Câu hỏi của tôi là, có ai thực hiện công việc để xác định xem URLEncode sản xuất dữ liệu hợp lệ x-www-form-urlencoded?

Trả lời

5

Vâng, tài liệu bạn liên kết là dành cho IIS 6 Server.UrlEncode, nhưng tiêu đề của bạn dường như hỏi về .NET System.Web.HttpUtility.UrlEncode. Sử dụng một công cụ như Reflector, chúng ta có thể thấy việc thực hiện sau này và xác định xem nó có đáp ứng thông số W3C hay không.

Đây là thói quen mã hóa cuối cùng được gọi là (chú ý, nó được định nghĩa cho một mảng byte và các quá tải khác có chuỗi cuối cùng chuyển đổi các chuỗi đó thành mảng byte và gọi phương thức này). Bạn sẽ gọi điều này cho mỗi tên và giá trị điều khiển (để tránh thoát các ký tự dành riêng = & được sử dụng làm dấu phân tách).

protected internal virtual byte[] UrlEncode(byte[] bytes, int offset, int count) 
{ 
    if (!ValidateUrlEncodingParameters(bytes, offset, count)) 
    { 
     return null; 
    } 
    int num = 0; 
    int num2 = 0; 
    for (int i = 0; i < count; i++) 
    { 
     char ch = (char) bytes[offset + i]; 
     if (ch == ' ') 
     { 
      num++; 
     } 
     else if (!HttpEncoderUtility.IsUrlSafeChar(ch)) 
     { 
      num2++; 
     } 
    } 
    if ((num == 0) && (num2 == 0)) 
    { 
     return bytes; 
    } 
    byte[] buffer = new byte[count + (num2 * 2)]; 
    int num4 = 0; 
    for (int j = 0; j < count; j++) 
    { 
     byte num6 = bytes[offset + j]; 
     char ch2 = (char) num6; 
     if (HttpEncoderUtility.IsUrlSafeChar(ch2)) 
     { 
      buffer[num4++] = num6; 
     } 
     else if (ch2 == ' ') 
     { 
      buffer[num4++] = 0x2b; 
     } 
     else 
     { 
      buffer[num4++] = 0x25; 
      buffer[num4++] = (byte) HttpEncoderUtility.IntToHex((num6 >> 4) & 15); 
      buffer[num4++] = (byte) HttpEncoderUtility.IntToHex(num6 & 15); 
     } 
    } 
    return buffer; 
} 

public static bool IsUrlSafeChar(char ch) 
{ 
    if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) || ((ch >= '0') && (ch <= '9'))) 
    { 
     return true; 
    } 
    switch (ch) 
    { 
     case '(': 
     case ')': 
     case '*': 
     case '-': 
     case '.': 
     case '_': 
     case '!': 
      return true; 
    } 
    return false; 
} 

Phần đầu tiên của quy trình đếm số ký tự cần được thay thế (dấu cách và ký tự an toàn không phải url).Phần thứ hai của thói quen phân bổ một bộ đệm mới và thực hiện thay thế:

  1. Url Nhân vật an toàn được lưu giữ như là: a-z A-Z 0-9()*-._!
  2. Spaces được chuyển đổi thành dấu cộng
  3. Tất cả các nhân vật khác được chuyển đổi thành %HH

bang RFC1738 (tôi nhấn mạnh):

Như vậy, chỉ alphanum erics, các ký tự đặc biệt "$ -_. +! * '(),", và
ký tự dành riêng được sử dụng cho mục đích riêng của chúng có thể được sử dụng
không được mã hóa trong URL.

Mặt khác, nhân vật mà không cần phải được mã hóa
(bao gồm cả chữ cái và số) có thể được mã hóa trong các chương trình cụ thể
một phần của một URL, miễn là họ không được sử dụng cho một reserved
mục đích.

Tập hợp các ký tự an toàn Url cho phép bởi UrlEncode là tập hợp con các ký tự đặc biệt được xác định trong RFC1738. Cụ thể, các ký tự $, bị thiếu và sẽ được mã hóa bởi UrlEncode ngay cả khi thông số kỹ thuật cho biết chúng an toàn. Vì chúng có thể được sử dụng chưa được mã hóa (và không phải là phải), nó vẫn đáp ứng thông số để mã hóa chúng (và đoạn thứ hai nói rõ ràng).

Đối với các ngắt dòng, nếu đầu vào có một chuỗi CR LF thì chuỗi đó sẽ bị xóa %0D%0A. Tuy nhiên, nếu đầu vào chỉ có LF thì đầu vào đó sẽ bị loại trừ %0A (vì vậy không có sự chuẩn hóa ngắt dòng trong quy trình này).

Bottom Line: Nó đáp ứng các đặc điểm kỹ thuật trong khi mã hóa bổ sung $,, và người gọi là trách nhiệm cung cấp ngắt dòng bình thường phù hợp trong đầu vào.

+1

Câu trả lời hay! Tôi cho rằng mã hóa ngắt dòng không đáp ứng được thông số kỹ thuật, nhưng với mục đích thực tế thì nó đủ gần. – hemp

Các vấn đề liên quan