Liệu một `+` trong lược đồ / máy chủ / đường dẫn URL có đại diện cho một khoảng trắng không?


224

Tôi biết rằng một +chuỗi truy vấn của URL đại diện cho một khoảng trắng. Đây có phải cũng là trường hợp bên ngoài khu vực chuỗi truy vấn? Điều đó có nghĩa là, URL sau:

http://a.com/a+b/c

thực sự đại diện cho:

http://a.com/a b/c

(và do đó cần phải được mã hóa nếu nó thực sự phải là một +), hoặc thực tế nó có đại diện a+b/ckhông?



4
Lưu ý rằng trong php urldecode giải mã% 2b (được mã hóa +) thành một khoảng trắng. Để tránh việc sử dụng này rawurldecode. Tôi nói điều này ở đây để tham khảo vì đây là kết quả được đánh giá cao trên google tìm kiếm "giải mã url url phá vỡ biểu tượng dấu cộng".
danielson317

Câu trả lời:


170
  • Phần trăm mã hóa trong phần đường dẫn của URL dự kiến ​​sẽ được giải mã, nhưng
  • bất kỳ +ký tự nào trong thành phần đường dẫn dự kiến ​​sẽ được xử lý theo nghĩa đen.

Để được rõ ràng: +chỉ là một ký tự đặc biệt trong thành phần truy vấn.


12
+1 Thật không may, nhiều "bộ mã hóa / mã hóa URL" ngoài tự nhiên không hiểu điều này. Ví dụ sislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder
leonbloy

11
@Stobor: cần trích dẫn.
bukzor

8
@Stobor RFC có bao giờ nói rằng +ký tự được hiểu là khoảng trắng trong thành phần truy vấn không? Hay nó chỉ đơn giản là một quy tắc "từ tự nhiên"?
Pacerier

44
@Pacerier và @bukzor: RFC 1738 (được sửa đổi bởi 2396 và 3986) xác định thành phần lược đồ ( http:), thẩm quyền ( //server.example.com) và đường dẫn ( /myfile/mypage.htm) và không xác định bất kỳ ý nghĩa đặc biệt nào cho +ký tự. Thông số HTML xác định thành phần truy vấn là loại ứng dụng mime / x-www-form-urlencoding được định nghĩa là "thay thế khoảng trắng bằng +và các ký tự đặc biệt khác như trong RFC1738". Vì vậy, nó không phải là "từ tự nhiên", mà là từ một tiêu chuẩn được chấp nhận (không phải RFC).
Stobor

2
Phương thức .NET Server.UrlEncodemã hóa sai các khoảng trắng dưới dạng kìm trong phần đường dẫn, vi phạm các quy tắc HTTP.
Suncat2000

243

Bạn có thể tìm thấy một danh sách đẹp các ký tự được mã hóa URL tương ứng trên W3Schools .

  • + trở thành %2B
  • không gian trở thành %20

18
Hoàn toàn hợp pháp khi các ký tự '+' theo nghĩa đen xuất hiện trong thành phần đường dẫn trên URL.
Sam Stainsby

4
Để có được một chữ + được nhận bởi phần cuối (hoặc, ít nhất là PHP), nó phải được mã hóa ba lần:%25252B
Ô

11
Câu trả lời này hoàn toàn không liên quan đến câu hỏi.
Nisse Engström

22

Các ký tự khoảng trắng chỉ có thể được mã hóa thành "+" trong một ngữ cảnh: các cặp khóa-giá trị ứng dụng / x-www-form-urlencoding.

RFC-1866 (đặc tả HTML 2.0), đoạn 8.2.1. đoạn 1. nói: "Các tên và giá trị của trường biểu mẫu được thoát: các ký tự khoảng trắng được thay thế bằng` + ', và sau đó các ký tự dành riêng được thoát ").

Dưới đây là ví dụ về một chuỗi như vậy trong URL trong đó RFC-1866 cho phép mã hóa không gian dưới dạng dấu cộng: " http://example.com/over/there?name=foo+bar ". Vì vậy, chỉ sau "?", Không gian có thể được thay thế bằng dấu cộng (trong các trường hợp khác, khoảng trắng phải được mã hóa thành% 20). Cách mã hóa dữ liệu biểu mẫu này cũng được đưa ra trong các thông số kỹ thuật HTML sau này, ví dụ: tìm các đoạn có liên quan về ứng dụng / x-www-form-urlencoding trong Đặc tả HTML 4.01, v.v.

Nhưng, bởi vì thật khó để luôn xác định chính xác bối cảnh, đó là cách tốt nhất để không bao giờ mã hóa các khoảng trắng thành "+". Tốt hơn là mã hóa phần trăm tất cả các ký tự ngoại trừ "không được bảo vệ" được xác định trong RFC-3986, tr.2.3. Dưới đây là một ví dụ mã minh họa những gì nên được mã hóa. Nó được đưa ra trong ngôn ngữ lập trình Delphi (pascal), nhưng rất dễ hiểu cách thức hoạt động của nó đối với bất kỳ lập trình viên nào, bất kể ngôn ngữ sở hữu:

(* percent-encode all unreserved characters as defined in RFC-3986, p.2.3 *)
function UrlEncodeRfcA(const S: AnsiString): AnsiString;
const    
  HexCharArrA: array [0..15] of AnsiChar = '0123456789ABCDEF';
var
  I: Integer;
  c: AnsiChar;
begin
 // percent-encoding, see RFC-3986, p. 2.1
  Result := S;
  for I := Length(S) downto 1 do
  begin
    c := S[I];
    case c of
      'A' .. 'Z', 'a' .. 'z', // alpha
      '0' .. '9',             // digit
      '-', '.', '_', '~':;    // rest of unreserved characters as defined in the RFC-3986, p.2.3
      else
        begin
          Result[I] := '%';
          Insert('00', Result, I + 1);
          Result[I + 1] := HexCharArrA[(Byte(C) shr 4) and $F)];
          Result[I + 2] := HexCharArrA[Byte(C) and $F];
        end;
    end;
  end;
end;

function UrlEncodeRfcW(const S: UnicodeString): AnsiString;
begin
  Result := UrlEncodeRfcA(Utf8Encode(S));
end;

0

sử dụng hàm encodeURIComponent để sửa url, nó hoạt động trên Browser và node.js

res.redirect("/signin?email="+encodeURIComponent("aaa+bbb-ccc@example.com"));


> encodeURIComponent("http://a.com/a+b/c")
'http%3A%2F%2Fa.com%2Fa%2Bb%2Fc'

1
Điều này không giải quyết câu hỏi. Và, mã hóa URL không chính xác, bằng một ngôn ngữ cụ thể (JavaScript) - tùy thuộc vào ngữ cảnh, bạn có thể không muốn mã hóa nơi bạn cần dấu gạch chéo (không phải bằng chữ) và dấu hai chấm (:) để URL hoạt động .
Gremio

Cảm ơn nó thực sự đã giúp tôi!
qwsd

-2

Hãy thử dưới đây:

<script type="text/javascript">

function resetPassword() {
   url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);
}
function fixEscape(str)
{
    return escape(str).replace( "+", "%2B" );
}
</script>

2
Tôi thấy rất kỳ quặc khi hai người đã bỏ phiếu cho câu trả lời này. Nó thực sự không có gì để làm với câu hỏi.
Andrew Barber

1
Còn đối với các nhân vật khác * @ - _ +. /
Ravi

1
@AndrewBarber Tại sao bạn thấy nó không liên quan? + trở thành% 2B
The Java Guy

Điều này sai vì rất nhiều lý do ... escapekhông được dùng nữa, thay vào đó bạn nên sử dụng encodeURIhoặc trong trường hợp phần truy vấn encodeURIComponent. Ngoài ra chuỗi tham số nên mã hóa theo w3c .
Christoph

-5

Bạn sẽ luôn mã hóa URL.

Đây là cách Ruby mã hóa URL của bạn:

irb(main):008:0> CGI.escape "a.com/a+b"
=> "a.com%2Fa%2Bb"

8
Tôi không chắc điều đó đúng. Theo RFC2394 ( ietf.org/rfc/rfc2394.txt ) kìm không phải là ký tự dành riêng trong đường dẫn (phân đoạn) của URI, chỉ có thành phần truy vấn. Điều đó dường như ngụ ý rằng họ không cần phải được mã hóa URL và do đó không nên được hiểu là khoảng trắng trong đường dẫn, chỉ trong truy vấn.
tlrobinson

3
rfc 1738 tuy nhiên không coi điểm cộng là khoảng trắng. Tất cả phụ thuộc vào việc được thực hiện bởi các chức năng mã hóa / giải mã của bạn. ví dụ: trong php, rawurlencode theo rfc 1738 trong khi urlencode theo rfc 2396.
Jonathan Fingerland

1
Xem, bây giờ tôi có một số nhầm lẫn bổ sung. Trong ví dụ bạn đã đưa cho tôi ở trên, a.com% 2Fa% 2Bb không phải là điều tôi muốn, ít nhất nó sẽ là a.com/a%2Bb. Đây là một URL thực tế tôi đang xử lý, không phải là một URL được truyền dưới dạng tham số trong chuỗi truy vấn. Đối với một nền tảng nhỏ có thể giúp làm rõ, Trình tìm kiếm Mac OS X đang trả lại URL hệ thống tệp cho tôi. Vì vậy, nếu tôi có một tệp có tên "a? + B.txt", nó sẽ trả về một cái gì đó trông giống như "tệp: //a%3F+b.txt", KHÔNG phải "tệp: //a%3F%2B.txt" . Là công cụ tìm không chính xác, hay là + trước chuỗi truy vấn thực sự là một dấu cộng?
Francisco Ryan Tolmasky I

2
Jonathan: Bạn có chắc 1738 nói + được bảo lưu? Tôi thấy: safe = "$" | "-" | "_" | "." | "+" không được giám sát = alpha | chữ số | an toàn | thêm cũng như: Do đó, chỉ các chữ số, các ký tự đặc biệt "$ -_. +! * '()," và các ký tự dành riêng được sử dụng cho mục đích dành riêng của chúng có thể được sử dụng không được mã hóa trong một URL.
tlrobinson

2
"Ngươi luôn luôn trốn thoát" cần nhiều phẩm chất hơn, và câu trả lời là không liên quan đến câu hỏi nào.
lỗi
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.