2012-07-15 27 views
17

Thực sự an toàn/hợp lệ để sử dụng tổng hợp mảng đa chiều trong chuỗi truy vấn URL?Cú pháp mảng có sử dụng dấu ngoặc vuông trong chuỗi truy vấn URL hợp lệ không?

http://example.com?abc[]=123&abc[]=456 

Có vẻ như để làm việc ở mọi trình duyệt và tôi luôn luôn nghĩ rằng nó là OK để sử dụng, nhưng accodring để bình luận trong bài viết này nó không phải là: http://www.456bereastreet.com/archive/201008/what_characters_are_allowed_unencoded_in_query_strings/#comment4

Tôi muốn nghe một ý kiến ​​thứ hai.

+0

"Đa chiều" là gì? Hoặc bạn đang đề cập đến các vars nhận được đại diện như là một mảng trong một ngôn ngữ kịch bản phía máy chủ? – arkascha

+0

@ yaascha yep, ý tôi là chuỗi truy vấn như thế này? A [b] [c] [d] [e] = f', kịch bản lệnh phía máy chủ sau đó xử lý nó như một mảng đa chiều –

Trả lời

12

Câu trả lời không đơn giản.

Phần sau được trích xuất từ ​​phần 3.2.2 của RFC 3986:

Hàng loạt xác định bởi một địa chỉ đen Giao thức Internet phiên bản 6
[RFC3513] hay muộn, được phân biệt bởi kèm theo IP đen
trong dấu ngoặc vuông ("[" và "] "). Đây là nơi duy nhất cho phép các ký tự dấu ngoặc vuông được phép trong cú pháp URI trong các ký tự URI là
.

có vẻ như để trả lời câu hỏi bằng cách nói rõ rằng dấu ngoặc vuông không được phép ở bất kỳ nơi nào khác trong URI. Nhưng có sự khác biệt giữa ký tự ngoặc vuông và ký tự dấu ngoặc vuông được mã hóa phần trăm.

Sau đây là trích ra từ đầu phần 3 của RFC 3986:

  1. Linh kiện Cú pháp

    Cú pháp URI chung bao gồm một chuỗi thứ bậc của
    thành phần được gọi là lược đồ, quyền hạn, đường dẫn, truy vấn và
    đoạn.

    URI = scheme ":" hier-part ["?" truy vấn] [ "#" fragment]

Vì vậy, các "truy vấn" là một thành phần của "URI".

Sau đây là trích ra từ phần 2.2 của RFC 3986:

2,2. Ký tự dành riêng

URI bao gồm các thành phần và thành phần phụ được phân cách bởi
ký tự trong bộ "đã đặt trước". Các ký tự này được gọi là
"được đặt trước" vì chúng có thể được xác định là dấu phân tách bằng
cú pháp chung, theo cú pháp của từng lược đồ cụ thể hoặc bằng cú pháp triển khai
cụ thể của thuật toán dereferencing của URI.
Nếu dữ liệu cho thành phần URI xung đột với mục đích của một ký tự được đặt trước, thì dữ liệu xung đột phải là
được mã hóa phần trăm trước khi URI được tạo.

reserved = gen-delims/sub-delims 

    gen-delims = ":"/"/"/"?"/"#"/"["/"]"/"@" 

    sub-delims = "!"/"$"/"&"/"'"/"("/")" 
      /"*"/"+"/","/";"/"=" 

dấu ngoặc vuông Vì vậy, có thể xuất hiện trong một chuỗi truy vấn, nhưng chỉ khi họ được trăm mã hóa. Trừ khi họ được không, để được giải thích thêm xuống trong phần 2.2:

URI ứng dụng sản xuất nên phần trăm mã hóa octet dữ liệu mà
tương ứng với ký tự trong tập reserved trừ khi những nhân vật
được phép đặc biệt bởi Lược đồ URI đại diện cho dữ liệu trong thành phần
này.Nếu một ký tự dành riêng được tìm thấy trong thành phần URI và
không có vai trò phân định nào được biết cho ký tự đó, thì phải là
được hiểu là biểu thị octet dữ liệu tương ứng với mã hóa
của ký tự này trong US-ASCII.

Vì vậy, vì dấu ngoặc vuông chỉ được phép trong phần tử "máy chủ", nên "được" mã hóa phần trăm trong các thành phần và thành phần phụ khác, và trong trường hợp này trong thành phần "truy vấn", trừ khi RFC 3986 cho phép không mã hóa rõ ràng dấu ngoặc vuông để đại diện cho dữ liệu trong thành phần truy vấn, mà không phải là. Tuy nhiên, nếu một "ứng dụng sản xuất URI" không thực hiện những gì nó "nên" làm, bằng cách để lại dấu ngoặc vuông không được mã hóa trong truy vấn, thì người đọc của URI không được từ chối URI ngay lập tức. Thay vào đó, các dấu ngoặc vuông sẽ được coi là thuộc về dữ liệu của thành phần truy vấn, vì chúng không được sử dụng như các dấu phân cách trong thành phần đó.

Đây là lý do tại sao, nó không vi phạm RFC 3986 khi PHP chấp nhận cả dấu ngoặc vuông không mã hóa và phần trăm dưới dạng ký tự hợp lệ trong chuỗi truy vấn và thậm chí gán cho chúng một mục đích đặc biệt. Tuy nhiên, có vẻ như các tác giả cố gắng tận dụng lỗ hổng này bằng cách không phần trăm mã hóa dấu ngoặc vuông vi phạm RFC 3986.

+0

"Dấu ngoặc vuông có thể xuất hiện trong chuỗi truy vấn nếu chúng được mã hóa phần trăm, trừ khi chúng không phải là" xD. câu trả lời rất hay. –

11

Theo RFC 3986, các Query component của một URL có ngữ pháp sau đây:

*(pchar/"/"/"?") 

Từ appendix A của cùng một RFC:

pchar   = unreserved/pct-encoded/sub-delims/":"/"@" 
[...] 
pct-encoded = "%" HEXDIG HEXDIG 

unreserved = ALPHA/DIGIT/"-"/"."/"_"/"~" 
[...]  
sub-delims = "!"/"$"/"&"/"'"/"("/")" 
      /"*"/"+"/","/";"/"=" 

giải thích của tôi về điều này là bất cứ điều gì mà isn' t:

ALPHA/DIGIT/"-"/"."/"_"/"~"/
    "!"/"$"/"&"/"'"/"("/")"/
    "*"/"+"/","/";"/"="/":"/"@" 

... phải được mã hóa bằng pct, tức là được mã hóa phần trăm. Vì vậy, [] nên được mã hóa theo phần trăm để theo RFC 3986.

+3

Bạn chắc chắn đúng, nhưng hãy giúp tôi sau đó với cách giải thích đó. Trích xuất bạn đưa ra là không đầy đủ, 'bảo lưu' không bao giờ được nhắc đến ở đây. Vì vậy, định nghĩa không có ý nghĩa như thế này. Khi tôi đọc nó, các dấu ngoặc vuông được định nghĩa là các ký tự dành riêng với một ý nghĩa đặc biệt (không chắc chắn), do đó chúng không nên được thoát nếu bạn muốn thể hiện ý nghĩa đó. Nếu bạn thoát khỏi bạn, bạn chỉ cần chuyển một chuỗi chứa các dấu ngoặc vuông làm giá trị của tham số. Vì vậy, tôi tự hỏi: Vâng, những gì _is_ thực sự ý nghĩa của dấu ngoặc vuông được dành riêng ký tự trong url? – arkascha

+0

Tôi để lại định nghĩa 'reserved' và' gen-delims' trong báo giá để dễ dàng thấy cách '[]' được phân loại trong ngữ pháp - thông báo rằng chỉ một tập con 'reserved' là một' pchar'. –

+0

Dấu ngoặc vuông được dành riêng cho các địa chỉ IP v6. http://tools.ietf.org/html/rfc3986#appendix-D.1, http://tools.ietf.org/html/rfc2732#section-2 –

1

Tôi luôn luôn có một sự cám dỗ để tìm loại truy vấn đó khi tôi phải vượt qua một mảng, nhưng tôi đã tránh xa nó. Lý do là:

  • Nó không được xóa trong RFC.
  • Các ngôn ngữ khác nhau có thể diễn giải một cách khác nhau.

Bạn có một vài lựa chọn để vượt qua một mảng: (? JSON có thể)

  • Mã hóa chuỗi đại diện của mảng
  • có các thông số như "VAL1 = blah & VAL2 = blah & .. "hoặc một cái gì đó tương tự.

Và nếu bạn chắc chắn về ngôn ngữ bạn đang sử dụng, bạn có thể (an toàn) tìm loại chuỗi truy vấn bạn có (Chỉ cần bạn cần% -encode []).

+0

Vì vậy đây sẽ là một URL multiarray hợp lệ? '? abc% 5B% 5D = 123 & abc% 5B% 5D = 456'. Rất xấu xí, tôi thấy lý do tại sao nó hiếm khi được sử dụng –

+1

Điều đó sẽ phụ thuộc vào cách ngôn ngữ xử lý nó. Tốt nhất là tránh xa nó. Để chính xác hơn một chút, chúng chỉ là cặp khóa-giá trị. Không có gì nhiều hơn, không có gì ít hơn và không có "mảng" trong đó. – SuperSaiyan

1

Sự hiểu biết của tôi rằng dấu ngoặc vuông không phải là công dân hạng nhất. Dưới đây là đoạn trích: http://tools.ietf.org/html/rfc1738

nhân vật khác là không an toàn vì các cổng và đại lý vận tải khác được biết là đôi khi sửa đổi các nhân vật như vậy. Các ký tự này là "{", "}", "|", "\", "^", "~", "[", "]" và "` ".

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