Ký tự Unicode trong URL


135

Trong năm 2010, bạn có phục vụ các URL chứa ký tự UTF-8 trong một cổng web lớn không?

Các ký tự Unicode bị cấm theo RFC trên các URL (xem tại đây ). Chúng sẽ phải được mã hóa phần trăm để tuân thủ các tiêu chuẩn.

Tuy nhiên, quan điểm chính của tôi là phục vụ các ký tự chưa được mã hóa cho mục đích duy nhất là có các URL trông đẹp mắt, do đó, phần trăm mã hóa đã bị loại bỏ.

Tất cả các trình duyệt chính dường như đang phân tích các URL đó đều ổn cho dù RFC nói gì. Tuy nhiên, ấn tượng chung của tôi là nó rất run khi rời khỏi miền của các trình duyệt web:

  • Các URL được sao chép + dán vào tệp văn bản, Email, thậm chí các trang web có mã hóa khác
  • Thư viện máy khách HTTP
  • Trình duyệt kỳ lạ, trình đọc RSS

Có phải ấn tượng của tôi là chính xác rằng rắc rối sẽ xảy ra ở đây, và do đó nó không phải là một giải pháp thực tế (nếu) bạn đang phục vụ một đối tượng phi kỹ thuật và điều quan trọng là tất cả các liên kết của bạn đều hoạt động tốt ngay cả khi được trích dẫn và truyền lại?

Có một số cách kỳ diệu để phục vụ các URL có giao diện đẹp trong HTML

http://www.example.com/düsseldorf?neighbourhood=Lörick

có thể được sao chép + dán với các ký tự đặc biệt nguyên vẹn, nhưng hoạt động chính xác khi được sử dụng lại trong các máy khách cũ?


16
Về phần mình, Firefox hiển thị các ký tự Unicode trong thanh URL của nó nhưng gửi chúng đến phần trăm máy chủ được mã hóa. Hơn nữa, khi người dùng sao chép URL từ thanh URL, Firefox đảm bảo rằng URL được mã hóa phần trăm được sao chép vào bảng tạm.
Siddhartha Reddy

Câu trả lời:


126

Sử dụng mã hóa phần trăm. Các trình duyệt hiện đại sẽ quan tâm đến các vấn đề hiển thị và dán và làm cho nó dễ đọc hơn. Ví dụ. http://ko.wikipedia.org/wiki/:

Chỉnh sửa: khi bạn sao chép một url như vậy trong Firefox, bảng tạm sẽ giữ dạng được mã hóa phần trăm (thường là một điều tốt), nhưng nếu bạn chỉ sao chép một phần của nó, nó sẽ vẫn không được mã hóa.


Wow, thực sự bạn đã đúng! Nếu bạn cắt, hãy tạo một URL được mã hóa%, Firefox sẽ biến nó thành thứ chính xác để hiển thị.
Dean Harding

Wow, tôi đã không nhận thức được điều này. Rất có thể đây là giải pháp tốt nhất!
Pekka

33
@Dean đó là một thay đổi khá gần đây - vào năm 2005, tất cả các wiki quốc tế trông giống như một% thực 6 %% 65% 73% 73.
Roman Starkov

2
Bạn có thể sử dụng URL UTF-8 chưa được mã hóa, cụ thể là IRI , trong các tài liệu HTML5 ngay bây giờ. Nếu bạn làm điều đó, tất cả các trình duyệt chính sẽ hiểu nó và hiển thị chính xác trong thanh địa chỉ của họ.
Oliver

Những byte nào trình duyệt hiện đại gửi đến máy chủ trong dòng yêu cầu GET /images/logo.png HTTP/1.1? Có phải họ luôn mã hóa phần trăm URL?
Flimm

87

Những gì Tgr nói. Lý lịch:

http://www.example.com/düsseldorf?neighbourhood=Lörick

Đó không phải là một URI. Nhưng đó một IRI .

Bạn không thể bao gồm IRI trong tài liệu HTML4; loại thuộc tính như hrefđược định nghĩa là URI chứ không phải IRI. Một số trình duyệt sẽ xử lý IRI ở đây dù sao, nhưng đó không thực sự là một ý tưởng hay.

Để mã hóa IRI thành URI, lấy đường dẫn và các phần truy vấn, UTF-8 - mã hóa chúng sau đó mã hóa phần trăm các byte không phải ASCII:

http://www.example.com/d%C3%BCsseldorf?neighbourhood=L%C3%B6rick

Nếu có các ký tự không phải ASCII trong phần tên máy chủ của IRI, vd. http://例え.テスト/, chúng đã được mã hóa bằng Punycode thay thế.

Bây giờ bạn có một URI. Đó là một URI xấu xí. Nhưng hầu hết các trình duyệt sẽ ẩn điều đó cho bạn: sao chép và dán nó vào thanh địa chỉ hoặc theo dõi nó trong một liên kết và bạn sẽ thấy nó được hiển thị với các ký tự Unicode gốc. Wikipedia đã sử dụng điều này trong nhiều năm, ví dụ:

http://en.wikipedia.org/wiki/ɸ

Một trình duyệt có hành vi không thể đoán trước và không phải lúc nào cũng hiển thị phiên bản IRI đẹp là ...

... Tốt, bạn biết đấy.


31
Tôi biết. Một ngày nọ, ai đó phải đưa một câu lạc bộ lớn và đập đầu những nhà phát triển Lynx đó. Cảm ơn thông tin nền tuyệt vời.
Pekka

2
@bobince Và một bot (chuyển nhanh đến 2013) cũng không thể xử lý các URI không IRI là ... ... tốt, bạn biết đấy: bingbot! Đi hình.
Tom Harrison

1
HTML5 cuối cùng cũng hỗ trợ IRI. Thông tin thêm về chủ đề có thể được tìm thấy trong câu trả lời này cho một câu hỏi liên quan .
Oliver

5
Re: IE không phải lúc nào cũng hiển thị các IRI đẹp - họ đang bảo vệ người dùng khỏi các cuộc tấn công lừa đảo dựa trên homograph. Hãy xem w3.org/I quốc tế / articles / idn -and- iiri (cụ thể là phần 'Tên miền - và lừa đảo') và blog.msdn.com/b/ie/archive/2006/07/31/684337.aspx
mã hóa

2
Tên miền không có gì để làm với điều này. Tất cả các trình duyệt không cho phép một loạt các ký tự để ngăn chặn lừa đảo. Hiển thị các ký tự không phải ASCII trong phần đường dẫn hoặc chuỗi truy vấn không tạo ra khả năng tương tự. IE chỉ đơn giản là không bận tâm để thực hiện nó. (Và Firefox là người duy nhất đã triển khai nó cho phần phân đoạn.)
Tgr

16

Tùy thuộc vào lược đồ URL của bạn, bạn có thể làm cho phần được mã hóa UTF-8 "không quan trọng". Ví dụ: nếu bạn xem URL chồng chéo, chúng có dạng sau:

http://stackoverflow.com/questions/2742852/unicode-char character-in-urls

Tuy nhiên, máy chủ không thực sự quan tâm nếu bạn nhận được phần sau khi định danh sai, vì vậy điều này cũng hoạt động:

http://stackoverflow.com/questions/2742852/ こ れ は 、 こ れ を 日本語 の テ

Vì vậy, nếu bạn có bố cục như thế này, thì bạn có khả năng có thể sử dụng UTF-8 trong phần sau mã định danh và sẽ không thực sự quan trọng nếu nó bị cắt xén. Tất nhiên điều này có lẽ chỉ hoạt động trong hoàn cảnh hơi chuyên biệt ...


Hừm, suy nghĩ rất thông minh! Vẫn có thể một số khách hàng bóp nghẹt các ký tự cho dù chúng nằm ở đâu trong chuỗi, nhưng nó sẽ loại bỏ tất cả các vấn đề với việc xáo trộn thông thường khi sao chép + dán URL, mà tôi nghĩ là phần quan trọng nhất. Chưa nhìn vào URL của SO theo cách đó. Cảm ơn!
Pekka

tốt, điều này vẫn để lại từ "câu hỏi" chưa được dịch, cộng với có nội dung sau hàm băm #, theo toàn bộ url, mặc dù vậy, mẹo rất hay !!
Evgeny

4
翻 訳 日本語 の URL を 作 っ た ね
Glutexo

6

Không chắc đó có phải là một ý tưởng hay không, nhưng như đã đề cập trong các nhận xét khác và như tôi diễn giải, nhiều ký tự Unicode có giá trị trong các URL HTML5 .

Ví dụ: các hreftài liệu nói rằng http://www.w3.org/TR/html5/links.html#attr-hyperlink-href :

Thuộc tính href trên phần tử a và khu vực phải có giá trị là URL hợp lệ có khả năng được bao quanh bởi khoảng trắng.

Sau đó, định nghĩa của "URL hợp lệ" trỏ đến http://url.spec.whatwg.org/ , định nghĩa các điểm mã URL là:

Chữ cái ASCII, "!", "$", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/" , ":", ";", "=", "?", "@", "_", "~" và các điểm mã trong phạm vi U + 00A0 đến U + D7FF, U + E000 đến U + FDCF , U + FDF0 thành U + FFFD, U + 10000 đến U + 1FFFD, U + 20000 đến U + 2FFFD, U + 30000 đến U + 3FFFD, U + 40000 đến U + 4FFFD, U + 50000 đến U + 5FFFD, U +60000 đến U + 6FFFD, U + 70000 đến U + 7FFFD, U + 80000 đến U + 8FFFD, U + 90000 đến U + 9FFFD, U + A0000 đến U + AFFFD, U + B0000 đến U + BFFFD, U + B0000 đến U + CFFFD, U + D0000 đến U + DFFFD, U + E1000 sang U + EFFFD, U + F0000 sang U + FFFFD, U + 100000 đến U + 10FFFD.

Thuật ngữ "điểm mã URL" sau đó được sử dụng trong một số phần của thuật toán phân tích cú pháp, ví dụ: đối với trạng thái đường dẫn tương đối :

Nếu c không phải là điểm mã URL và không phải là "%", lỗi phân tích cú pháp.

Đồng thời, trình xác thực http://validator.w3.org/ chuyển cho các URL như "你好"và không chuyển cho các URL có các ký tự như dấu cách"a b"

Liên quan: Những ký tự nào làm cho URL không hợp lệ?


Nhưng cả hai URL ( "你好""a b") phải được mã hóa phần trăm khi thực hiện yêu cầu HTTP phải không?
Utku

@Utku đối với "a b"tôi khá chắc chắn là có vì không gian không nằm trong danh sách được phép ở trên. Đối với "你好", đó chắc chắn là ý tưởng tốt hơn để mã hóa phần trăm, nhưng tôi không biết liệu đó chỉ là một câu hỏi về "việc triển khai không đủ tốt" hay "tiêu chuẩn nói như vậy". Tiêu chuẩn HTML dường như cho phép những nhân vật đó. Nhưng tôi nghĩ điều này được chỉ định bởi tiêu chuẩn HTTP, không phải HTML. Xem thêm: stackoverflow.com/questions/912811/
Mạnh

Vâng, tôi đã nghĩ về tiêu chuẩn HTTP, không phải HTML.
Utku

5

Vì tất cả các ý kiến ​​này đều đúng, bạn nên lưu ý rằng theo như ICANN chấp thuận các ký tự tiếng Ả Rập (tiếng Ba Tư) và tiếng Trung để được đăng ký làm Tên miền, tất cả các công ty sản xuất trình duyệt (Microsoft, Mozilla, Apple, v.v.) phải hỗ trợ Unicode trong URL mà không cần bất kỳ mã hóa nào và Google có thể tìm kiếm được, v.v.

Vì vậy, vấn đề này sẽ giải quyết càng sớm càng tốt.


2
@Nasser: Đúng - hiện tại chúng tôi cũng có các ký tự đặc biệt trong các miền tiếng Đức - nhưng chúng cũng được mã hóa thành các ký tự ASCII bằng Punycode . Mặc dù chúng chắc chắn hoạt động trong các trình duyệt chính, nhưng sẽ còn rất lâu nữa mọi thư viện máy khách HTTP và ứng dụng kỳ lạ sẽ có thể xử lý các ký tự Unicode chưa được mã hóa.
Pekka

@Pekka, tôi không chắc nhưng như tôi đã nghe, tất cả các trình duyệt phải hỗ trợ URL Unicode vào quý 4 năm 2010 (Tôi không chắc chắn)
Nasser Hadjloo

Vấn đề rất phức tạp bởi thực tế không phải mọi tác nhân người dùng đều là trình duyệt web. Ví dụ lớn nhất là chính google: Nó không sử dụng các trình duyệt web phổ biến để thực hiện thu thập thông tin. Vì vậy, nhiều thư viện cho tương tác API, v.v. - URL gần như ở mọi nơi, không chỉ trong WWW. Có lẽ ngay cả trên hệ thống tập tin của bạn ngay bây giờ.
Cornelius

1

Sử dụng hình thức mã hóa phần trăm . Ví dụ, một số máy tính (chủ yếu là cũ) chạy Windows XP không hỗ trợ Unicode, mà là mã hóa ISO. Đó là lý do URL được mã hóa phần trăm được phát minh. Ngoài ra, nếu bạn cung cấp một URL được in trên giấy cho người dùng, có chứa các ký tự không thể gõ dễ dàng, người dùng đó có thể gặp khó khăn khi nhập nó (hoặc chỉ cần bỏ qua nó). Dạng mã hóa phần trăm thậm chí có thể được sử dụng trong nhiều máy móc lâu đời nhất từng tồn tại (mặc dù tất nhiên chúng không hỗ trợ internet).

Mặc dù có một nhược điểm, vì các ký tự được mã hóa phần trăm dài hơn các ký tự gốc, do đó có thể dẫn đến các URL thực sự dài. Nhưng chỉ cần cố gắng bỏ qua nó hoặc sử dụng trình rút ngắn URL (tôi sẽ khuyên dùng goo.gl trong trường hợp này, điều này tạo ra một URL dài 13 ký tự). Ngoài ra, nếu bạn không muốn đăng ký tài khoản Google, hãy thử bit.ly (bit.ly tạo các URL dài hơn một chút, với độ dài là 14 ký tự).


Tại sao tôi muốn hỗ trợ các máy tính lỗi thời vẫn sử dụng Windows XP?
Mateus Felipe

0

Đối với tôi đây là cách chính xác, Điều này chỉ hoạt động:

    $linker = rawurldecode("$link");
    <a href="<?php echo $link;?>"   target="_blank"><?php echo $linker ;?></a>

Điều này đã làm việc và bây giờ các liên kết được hiển thị đúng:

http://newspaper.annahar.com/article/121638 -معرض - جوزف-حرب-في-غغللل

Liên kết tìm thấy trên:

http://www.galeriejaninerubeiz.com/newsite/news


2
"Các liên kết được hiển thị đúng" - ngoại trừ trình phân tích cú pháp đánh dấu StackOverflow không diễn giải các URL như dự định!
MrWhite
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.