Unicode karakterlerini URL kodlamanın doğru yolu nedir?


107

Standart olmayan% uxxxx şemasını biliyorum, ancak bu plan W3C tarafından reddedildiği için akıllıca bir seçim gibi görünmüyor.

Bazı ilginç örnekler:

Kalp karakteri. Bunu tarayıcıma yazarsam:

http://www.google.com/search?q=♥

Sonra kopyalayıp yapıştırın, bu URL'yi görüyorum

http://www.google.com/search?q=%E2%99%A5

Firefox (veya Safari) bunu yapıyor gibi görünmesini sağlar.

urllib.quote_plus(x.encode("latin-1"))
'%E2%99%A5'

Bu, üçlü nokta karakteri gibi Latin-1'de kodlanamayan şeyler dışında anlamlıdır.

URL'yi yazarsam

http://www.google.com/search?q=…

tarayıcıma kopyalayıp yapıştırın,

http://www.google.com/search?q=%E2%80%A6

geri. Bu yapmanın sonucu gibi görünüyor

urllib.quote_plus(x.encode("utf-8"))

bu mantıklı çünkü… Latin-1 ile kodlanamaz.

Ama o zaman tarayıcının UTF-8 veya Latin-1 ile kod çözmeyi nasıl bildiği bana açık değil.

Bu belirsiz göründüğü için:

In [67]: u"…".encode('utf-8').decode('latin-1')
Out[67]: u'\xc3\xa2\xc2\x80\xc2\xa6'

çalışır, bu yüzden tarayıcının bunu UTF-8 veya Latin-1 ile çözüp çözmeyeceğini nasıl anladığını bilmiyorum.

Başa çıkmam gereken özel karakterlerle yapmam gereken doğru şey nedir?


19
Her iki örneğiniz de UTF-8 olarak kodlanmıştır. İlki kesinlikle Latin-1 değil, üç bayt uzunluğunda olduğu düşünüldüğünde ...
Jakob Borg

2
% E2% 99% A5, UTF-8'deki "siyah kalp uygunluğunun" bayt değerleri için onaltılıktır . Bu siyah kalp Latin-1 karakter kümesinin bir parçası değil .
Hawkeye Parker

Bir tarayıcının tam olarak nasıl ve neyi kodladığını (ve diğer birçok yararlı bilgiyi) güvenilir bir şekilde görmek için, çoğu modern tarayıcıda yerleşik olarak bulunan geliştirici araçlarını kullanın veya Fiddler gibi ücretsiz bir HTTP hata ayıklayıcı edinin .
Hawkeye Parker

Yanıtlar:


65

Her zaman UTF-8 ile kodlardım. Yüzde kodlamayla ilgili Wikipedia sayfasından :

Genel URI sözdizimi, bir URI'deki karakter verilerinin temsilini sağlayan yeni URI şemalarının, gerçekte, çevrilmeden ayrılmamış karakterleri temsil etmesi ve diğer tüm karakterleri UTF-8'e göre bayta dönüştürmesi gerektiğini ve daha sonra bu değerleri yüzde olarak kodlayın. Bu gereklilik, Ocak 2005'te RFC 3986'nın yayınlanmasıyla ortaya çıktı . Bu tarihten önce tanıtılan URI şemaları etkilenmez.

Görünüşe göre geçmişte URL kodlama yapmanın başka kabul edilmiş yolları olduğu için, tarayıcılar bir URI'nin kodunu çözmek için birkaç yöntem deniyor, ancak kodlamayı yapan sizseniz UTF-8 kullanmalısınız.


8
UTF-8 , eski URL standardının yerini alan yeni IRI standardının (RFC 3987, tools.ietf.org/html/rfc3986 ) izin verdiği tek kodlama olduğu için de kullanılmalıdır .
Remy Lebeau

3
Başkalarının da benim kadar şaşırması durumunda, @ RemyLebeau'nun yorumundaki metin RFC3987'den bahseder, ancak bağlantı eski spesifikasyon 3896'ya yöneliktir. Doğru URL açıkça tools.ietf.org/html/rfc3987
üçlü

Evet, bunun için üzgünüm. URI, RFC 3986 tarafından tanımlanır, IRI, RFC 3987 tarafından tanımlanır.
Remy Lebeau

10

Genel kural, tarayıcıların form yanıtlarını formun sunulduğu sayfanın içerik türüne göre kodlaması gibi görünüyor. Bu, sunucu bize "text / xml; charset = iso-8859-1" gönderirse, yanıtların aynı formatta olmasını bekledikleri tahminidir.

URL çubuğuna yalnızca bir URL giriyorsanız, tarayıcının üzerinde çalışacak bir temel sayfası yoktur ve bu nedenle yalnızca tahmin etmesi gerekir. Yani bu durumda her zaman utf-8 yapıyor gibi görünüyor (çünkü her iki girdiniz de üç sekizli form değerleri üretti).

Üzücü gerçek şu ki, AFAIK'in bir sorgu dizesindeki değerlerin veya URL'deki herhangi bir karakterin hangi karakter olarak yorumlanması gerektiğine dair bir standart yoktur. Sorgu dizesinde değerlerin durumunda En azından, ille olduğunu varsaymak için hiçbir neden yok yapmak karakterlere karşılık gelmektedir.

Bu karakter sorgu dizesi, örneğin Tomcat, sen request.setEncoding () (veya benzeri bir yöntem) aramak zorunda --- olarak kodlanmış bekliyoruz seti sunucu çerçevesini anlatmak zorunda bilinen problem önce size request.getParameter () yöntemlerinden herhangi birini çağırın. Bu konudaki dokümantasyon eksikliği, muhtemelen birçok geliştiricinin problemin farkında olmamasını yansıtıyor. (Java ile görüşülen kişilere düzenli olarak Okuyucu ve InputStream arasındaki farkın ne olduğunu soruyorum ve düzenli olarak boş bakışlar alıyorum)


6
RFC 3987 ( tools.ietf.org/html/rfc3986 ) standart bir kodlamayı tanımlar - Kodlanmamış olmasına izin verilmeyen karakterleri kodlarken UTF-8 kullanılmalıdır.
Remy Lebeau

8

IRI ( RFC 3987 ), URI / URL ( RFC 3986 ve daha eski) standartlarının yerini alan en son standarttır. URI / URL, Unicode'u yerel olarak desteklemez (pekala, RFC 3986 bunu desteklemek için gelecekteki URI / URL tabanlı protokoller için hükümler ekler, ancak geçmiş RFC'leri güncellemez). "% UXXXX" düzeni, bazı durumlarda Unicode'a izin veren standart olmayan bir uzantıdır, ancak herkes tarafından evrensel olarak uygulanmaz. Öte yandan IRI, Unicode'u tam olarak destekler ve metnin yüzde kodlanmadan önce UTF-8 olarak kodlanmasını gerektirir.


Protokollerde bir güncelleme görmek istiyorum, böylece unicode yalnızca yüzde kodlama yoluyla değil, URL'lerde tam olarak destekleniyor.
Mathieu J.

1
IRI'lar, ayrılmış karakterlerin kodlanması gereken birkaç durum dışında, kodlanmamış Unicode karakterlere izin verir.
Remy Lebeau

6

IRI'lar URI'lerin yerini almaz, çünkü HTTP dahil olmak üzere bazı bağlamlarda yalnızca URI'lara (etkili, ASCII) izin verilir.

Bunun yerine, bir IRI belirtirsiniz ve telden çıkarken bir URI'ye dönüştürülür.


0

İlk soru, ihtiyaçlarınız nelerdir? UTF-8 kodlaması, ucuz bir düzenleyiciyle oluşturulan metni almak ile çok çeşitli dilleri desteklemek arasında oldukça iyi bir uzlaşmadır. Kodlamayı tanımlayan tarayıcıyla ilgili olarak, yanıt (web sunucusundan) tarayıcıya kodlamayı bildirmelidir. Yine de çoğu tarayıcı tahmin etmeye çalışacaktır, çünkü çoğu durumda bu eksik veya yanlıştır. Varsayılan kodlamaya uymayan bir karakter olup olmadığını görmek için bir miktar sonuç akışı okuyarak tahmin ederler. Şu anda tüm tarayıcılar (? Bunu kontrol etmedim, ancak doğruya oldukça yakın) varsayılan olarak utf-8 kullanıyor.

Öyleyse, diğer kodlama şemalarından birini kullanmak için ikna edici bir nedeniniz yoksa, utf-8 kullanın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.