2010-12-09 4 views
11

Also ich versuche, eine Rails-URL-Helfer (page_url) zu verwenden, um URLs zu erstellen, die Sonderzeichen einschließlich Et-Zeichen enthalten. Die meisten Fälle funktionieren wie Sie es erwarten würde:Rails URL-Helper, der nicht für kaufmännisches Und-Zeichen

(rdb:1) page_url('foo', :host => 'host') 
"http://host/pages/foo" 
(rdb:1) page_url('foo_%_bar', :host => 'host') 
"http://host/pages/foo_%25_bar" 

Aber aus irgendeinem seltsamen Grund, Et-Zeichen sind nicht entgangen:

(rdb:1) page_url('foo_&_bar', :host => 'host') 
"http://host/pages/foo_&_bar" 

Und wenn ich sie vor-entkommen, sie beschädigt werden:

(rdb:1) page_url('foo_%26_bar', :host => 'host') 
"http://host/pages/foo_%2526_bar" 

CGI::escape, auf der anderen Seite, entgeht sie fein:

(rdb:1) CGI::escape('foo_&_bar') 
"foo_%26_bar" 

Was ist los, und wie kann ich das umgehen? (Mit etwas schöner als , das ist.)

+0

Hmmm .. Ich kann nicht wirklich einen Rails-Helfer namens page_url finden (sah auf der Apidock-Website) - bist du sicher, dass das der richtige Methodenname ist? Meinst du stattdessen url_for? –

+0

Ich habe einen ActiveRecord namens "page", der _url Helfer dafür wird automatisch erstellt. – jpatokal

+0

Ah - richtig. Das ist in deiner Beschreibung nicht durchgekommen :) –

Antwort

14

Ich kann Ihnen nicht einen schöneren Weg sagen, um damit umzugehen - aber ich kann erklären, warum es passiert.

Ampersands sind keine ungültigen Zeichen für eine URL. Sonst hättest du Probleme mit: "http://host/pages/foo?bar=baz&style=foo_style" oder was auch immer.

Bearbeiten: Graben tiefer in den Quellcode, sieht es aus wie Rails CGI.escape nur auf Parameter verwendet.

Der Helfer, URL-Generatoren verwenden url_for (unter der Decke), die schließlich ruft: http://apidock.com/rails/ActionController/Routing/Route/generate Welche Sachen tief in den sprivate-Methoden des Quellcodes ruft ... aber schließlich endet cgi.escape Aufruf (zuerst in actionpack/lib/action_controller/routing/route.rb dann in actionpack/lib/action_controller/routing/segments.rb)

Endergebnis ist, dass auf der URL selbst, Schienen verwendet URI.escape - was insbesondere tut aktualisieren Sie nicht kaufmännisches Und-Zeichen überhaupt:

>> CGI.escape('/my_foo_&_bar') 
=> "%2Fmy_foo_%26_bar" 
>> URI.escape('/my_foo_&_bar') 
=> "/my_foo_&_bar" 

Es gibt Gegenwärtig kann man nichts dagegen tun, ohne eine echte Feature-Anfrage ins Rails-Team zu stellen.

... es sei denn, Sie haben die Möglichkeit, zu wählen, nicht Et-Zeichen in URLs verwenden Sie immer sie aus sich selbst für alle URLs gsub können:

def my_clean_url(the_url) 
    return the_url.gsub(/&/,'_') 
end 
>> my_clean_url('/my_foo_&_bar') 
=> "/my_foo___bar" 

page_url(my_clean_url('/my_foo_&_bar')) 
+1

Das Problem ist, dass die & wird von der zugrunde liegenden (nicht-Ruby) App als normales Zeichen verwendet, aber viele URL-Parser sehen es als Parametertrennzeichen und hacken die URL, wenn sie es sehen. Durch die Codierung wird sichergestellt, dass es intakt bleibt. – jpatokal

+0

Ah yup - das macht Sinn. –

+0

Danke für die Detektivarbeit! – jpatokal

6

Für alle diejenigen, die versuchen, nur etwas zu kodieren anders als az, AZ, 0-9 und Unterstrich:

Angenommen, Sie haben Inhalte, die z kaufmännisches Und-Zeichen und Sie möchten diesen Inhalt als body Parameter für eine mailto Verbindung verwenden: Ohne /\W/ würde das kaufmännische Und (das ein sicheres URI-Zeichen ist) nicht codiert werden und daher die Verbindung teilweise unterbrechen.

Verwandte Themen