2016-06-02 14 views
3

Ich habe ein einfaches Problem: Benutzer können URLs durch bestimmte Eingabe in einem Formular auf meiner Website posten. Ich möchte die gepostete URL verschlüsseln, weil Benutzer manchmal URLs mit seltsamen und/oder nicht ASCII-Zeichen senden (wie é à ç ...). Zum Beispiel: https://www.example.com/url-déjà-vuRuby - wie URL zu kodieren, ohne bereits kodierte Zeichen neu zu kodieren

Also habe ich versucht URI.escape('https://www.example.com/url-déjà-vu') zu verwenden, die funktioniert, aber dann, wenn Sie die folgende URL haben: URI.escape('https://somesite.com/page?stuff=stuff&%20') Sie erhalten: => "https://somesite.com/page?stuff=stuff&%2520"

Das Zeichen% codiert und sollte nicht als% betragen 20 schon ein codiertes Zeichen. Dann dachte ich, ich könnte dies tun:

URI.escape(URI.decode('https://somesite.com/page?stuff=stuff&%20')) 
=> "https://somesite.com/page?stuff=stuff&%20" 

Aber es gibt ein Problem, wenn Sie ein „/“ codiert in Ihrer URL, zum Beispiel haben:

URI.escape(URI.decode('http://example.com/a%2fb')) 
=> "http://example.com/a/b" 

Der „/“ verschlüsselt bleiben sollte.

Also ... alles zusammen: Ich möchte URLs von Benutzern gepostet kodieren, aber unverändert codierte Zeichen in Ruby unverändert lassen. Irgendeine Idee, wie ich das machen könnte, ohne Kopfschmerzen zu bekommen?

Thanks :)

+0

Woah! Sie lassen Ihre Nutzer URLs über ein Formular posten? Wofür ist das? Einfache Neugier –

+0

Ich sehe nicht, warum Sie überrascht sind, sagen wir, es ist genau das gleiche wie wenn Sie Ihr Profil in Stack-Überlauf bearbeiten und auf "Web-Präsenz" gehen. Sie haben 3 Felder dort, wo Sie absolute URL zu Ihrer Website, Twitter-Profil oder Github-Profil hinzufügen können. Zum Beispiel ist hier eine zufällige Link in Profil-URL, die ein Akzent-Zeichen enthält und die tatsächlich funktioniert und sollte richtig codiert werden: https://fr.linkedin.com/in/aurélien-benjamin-a4196b27. – Kulgar

+0

@RubenBarbosa Dies ist ein Formular, in dem Sie Ihr StackOverflow-Profil bearbeiten können. Sie können eine URL unter dem Feld "Website-Link" veröffentlichen. Was ist überraschend daran, eine URL zu posten? http://stackoverflow.com/users/edit/5030878 – Hoa

Antwort

4

Ich denke, kann nicht von einer Art und Weise, dies zu tun, das nicht ein wenig von einer Flickschusterei ist. Also schlage ich ein bisschen Kludge vor.

scheint in allen Fällen so zu funktionieren, wie Sie möchten, außer wenn die Zeichen bereits codiert sind. In diesem Sinne können wir das Ergebnis von URI.encode nehmen und String#gsub verwenden, um nur diese Zeichen zu "entschlüsseln".

Der folgende reguläre Ausdruck sucht nach %25 (eine codierte %), gefolgt von zwei Hexadezimalziffern, z. %252f zurück in %2f:

require "uri" 

DOUBLE_ESCAPED_EXPR = /%25([0-9a-f]{2})/i 

def escape_uri(uri) 
    URI.encode(uri).gsub(DOUBLE_ESCAPED_EXPR, '%\1') 
end 

puts escape_uri("https://www.example.com/url-déjà-vu") 
# => https://www.example.com/url-d%C3%A9j%C3%A0-vu 

puts escape_uri("https://somesite.com/page?stuff=stuff&%20") 
# => https://somesite.com/page?stuff=stuff&%20 

puts escape_uri("http://example.com/a%2fb") 
# => http://example.com/a%2fb 

versprechen ich nicht, dass dies ist narrensicher, aber hoffentlich hilft es.

+0

Das ist eigentlich eine clevere Lösung. Ich werde mit anderen Mitgliedern meiner Mitentwickler sehen, wenn sie irgendwelche Nachteile denken könnten ... persönlich, ich nicht :) Vielen Dank! – Kulgar

+1

Ok, ich habe die Antwort akzeptiert, da es scheint zu tun, was ich will :) Aber wie du gesagt hast, können wir nicht wissen, ob es immer narrensicher sein wird. Man sollte also vorsichtig mit dieser Lösung umgehen und gute Tests durchführen, um unerwartete Fehler zu vermeiden. – Kulgar