2012-05-10 6 views
7

Ich verwende Ruby, um eine URL einer Datei zu extrahieren, um sie herunterzuladen und herunterzuladen. Der Dateiname ist UTF-8-Zeichen, ex:Wie führe ich eine URL-Codierung von ASCII-Zeichen durch?

www.domain.com/.../ÖÇÄÜ360ÓïÒôÖúÀí.txt 

Beim Versuch, die oben genannte URL zum Download, es funktioniert nicht. URI::escape erhält man eine URI, die auch nicht funktioniert:

www.domain.com/.../%C3%96%C3%87%C3%84%C3%9C360%C3%93%C3%AF%C3%92%C3%B4%C3%96%C3%BA%C3%80%C3%AD.txt 

Aber wenn ich die URL Encoding Reference folgen, es funktioniert:

www.domain.com/.../%D6%C7%C4%DC360%D3%EF%D2%F4%D6%FA%C0%ED.txt 

ich für eine Funktion in Ruby zu suchen versucht, die genau tut gleiche Kodierung, aber ich konnte keine finden. Bevor ich versuche, eine Funktion zu schreiben, die die Tabelle in dem obigen Link implementiert, möchte ich fragen, ob jemand eine existierende Bibliothek kennt, die dies tut. Und wenn ich mich dazu entscheide, welche Reihe von Zeichen ich verschlüsseln sollte, offensichtlich nicht alles.

Ich bin mit JRuby 1.6.2 mit RUBY_VERSION => "1.8.7"

+1

Die Bytes C3 96 sind ein UTF-8-codiertes Ö. Das gleiche Zeichen wird in ASCII als das einzelne Byte D6 dargestellt. Eine Möglichkeit, das Problem anzugehen, besteht darin, Ihre UTF-8-Zeichen in ASCII zu konvertieren, wo Sie können, und dann URI :: escape. Aber das hilft dir nicht für Unicode-Zeichen, die kein ASCII-Äquivalent haben. –

+0

Haben Sie ['CGI.escape'] (http://ruby-doc.org/stdlib-1.9.3/libdoc/cgi/rdoc/CGI.html#method-c-escape) ausprobiert? –

+0

@DavidGorsline: Dies funktioniert nicht. Ich lande mit '?' für alle Zeichen außer "360" und ".txt". Das obige Beispiel ist ein echtes Beispiel, wenn Sie irgendwelche Ideen haben, können Sie sie auf der Zeichenkette "..." testen ... und lassen Sie mich wissen, wie es geht. Vielen Dank für Ihre Hilfe. – Rami

Antwort

15

Oh, die Freuden des Zeichenkodierungen!

Was passiert hier ist wie folgt. Ruby intern speichert die Zeichenfolge, die Sie extrahiert haben, als eine Bytefolge, bei der es sich um die utf-8-Codierung des Dateinamens handelt. Wenn Sie auf es aufrufen, werden diese Byte in %xy-Format maskiert und die resultierende Zeichenfolge, die jetzt nur aus Bytes in dem ASCII-Bereich besteht, wird als die URL verwandt.

Der empfangende Server interpretiert jedoch diese Bytes (nachdem sie von %xy Formular unescaping) als ob sie in einer anderen Codierung waren, in diesem Fall ISO-8859-1, und so entspricht der daraus resultierende Dateiname nichts hat.

Hier ist eine Demonstration mit Ruby 1.9, da es eine bessere Unterstützung für Kodierungen bietet.

1.9.3-p194 :003 > f 
=> "ÖÇÄÜ360ÓïÒôÖúÀí.txt" 
1.9.3-p194 :004 > f.encoding 
=> #<Encoding:UTF-8> 
1.9.3-p194 :005 > URI.escape f 
=> "%C3%96%C3%87%C3%84%C3%9C360%C3%93%C3%AF%C3%92%C3%B4%C3%96%C3%BA%C3%80%C3%AD.txt" 
1.9.3-p194 :006 > g = f.encode 'iso-8859-1' 
=> "\xD6\xC7\xC4\xDC360\xD3\xEF\xD2\xF4\xD6\xFA\xC0\xED.txt" 
1.9.3-p194 :007 > g.encoding 
=> #<Encoding:ISO-8859-1> 
1.9.3-p194 :008 > URI.escape g 
=> "%D6%C7%C4%DC360%D3%EF%D2%F4%D6%FA%C0%ED.txt" 

Die Lösung in diesem Fall ist daher die Zeichenfolge als ISO-8859-1 zu kodieren, bevor sie entkommen. In Ruby 1.9 Sie dies tun, wie oben, in früheren Versionen können Sie Iconv verwenden (Ich gehe davon aus JRuby Iconv enthält, ich bin eigentlich nicht so vertraut mit JRuby):

1.8.7 :001 > f 
=> "\303\226\303\207\303\204\303\234360\303\223\303\257\303\222\303\264\303\226\303\272\303\200\303\255.txt" 
1.8.7 :005 > g = Iconv.conv('iso-8859-1', 'utf-8', f) 
=> "\326\307\304\334360\323\357\322\364\326\372\300\355.txt" 
1.8.7 :006 > URI.escape f 
=> "%C3%96%C3%87%C3%84%C3%9C360%C3%93%C3%AF%C3%92%C3%B4%C3%96%C3%BA%C3%80%C3%AD.txt" 
1.8.7 :007 > URI.escape g 
=> "%D6%C7%C4%DC360%D3%EF%D2%F4%D6%FA%C0%ED.txt" 

Beachten Sie, dass in der Regel können Sie‘ t hängen vom Server ab, der eine bestimmte Kodierung verwendet. Es sollte utf-8 verwenden, ist aber offensichtlich nicht in diesem Fall.

+0

Super, danke! – Rami

+0

Dies war sehr hilfreich hatte keine Ahnung, dass ich nach der Codierung URI.escape brauchte. – KnuturO

Verwandte Themen