Qual è la differenza tra URI.escape
e CGI.escape
e quale dovrei usare?
Qual è la differenza tra URI.escape
e CGI.escape
e quale dovrei usare?
Risposte:
C'erano alcune piccole differenze, ma il punto importante è che URI.escape
è stato deprecato in Ruby 1.9.2 ... quindi usa CGI::escape
o ERB :: Util.url_encode .
C'è una lunga discussione su ruby-core per gli interessati che menziona anche WEBrick :: HTTPUtils.escape e WEBrick :: HTTPUtils.escape_form .
ERB::Util.url_encode
che utilizza correttamente %20
per gli spazi
Qual è la differenza tra un'ascia e una spada e quale dovrei usare? Bene dipende da cosa devi fare.
URI.escape
doveva codificare una stringa (URL) in, cosiddetta " codifica in percentuale ".
CGI::escape
proviene dalle specifiche CGI , che descrive come i dati dovrebbero essere codificati / decodificati tra il server Web e l'applicazione.
Ora, supponiamo che tu debba sfuggire a un URI nella tua app. È un caso d'uso più specifico. Per questo, la comunità di Ruby ha usato URI.escape
per anni. Il problema URI.escape
era che non poteva gestire le specifiche RFC-3896.
URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog"
URI.escape
è stato contrassegnato come obsoleto:
Inoltre l'attuale URI.encode è gsub semplice. Ma penso che dovrebbe dividere un URI in componenti, quindi sfuggire a ciascun componente e infine unirli.
Quindi l'attuale URI.encode è considerato dannoso e deprecato. Questo verrà rimosso o cambierà drasticamente il comportamento.
Qual è la sostituzione in questo momento?
Come ho detto sopra, il codice URI corrente è errato a livello di specifica. Quindi non forniremo la sostituzione esatta. La sostituzione varierà a seconda del suo caso d'uso.
Sfortunatamente non c'è una sola parola al riguardo nei documenti, l'unico modo per saperlo è controllare la fonte, o eseguire lo script con avvertimenti a livello dettagliato ( -wW2
) (o usare un po 'di Google-Fu).
Alcuni hanno proposto di utilizzare CGI::Escape
per i parametri della query, poiché non è stato possibile sfuggire a un intero URI:
CGI::escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http%3A%2F%2Fgoogle.com%2Ffoo%3Fbar%3Dat%23anchor%26title%3DMy+Blog+%26+Your+Blog"
CGI::escape
dovrebbe essere usato solo per i parametri della query, ma i risultati saranno, ancora una volta, contro la specifica. In realtà il caso d'uso più comune è l'escaping dei dati del modulo, ad esempio durante l'invio di una application/x-www-form-urlencoded
richiesta POST.
Anche menzionato WEBrick::HTTPUtils.escape
non è molto di miglioramento (di nuovo è solo gsub
un'opzione semplice , che è, IMO, anche peggiore di URI.escape
):
WEBrick::HTTPUtils.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog"
Il più vicino alla specifica sembra essere la gemma indirizzabile :
require 'addressable/uri'
Addressable::URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at#anchor&title=My%20Blog%20&%20Your%20Blog"
Si noti che, a differenza di tutte le opzioni precedenti, Indirizzabile non sfugge #
e questo è il comportamento previsto. vuoi mantenere l' #
hash nel percorso URI ma non nella query URI.
L'unico problema rimasto è che non abbiamo evitato correttamente i nostri parametri di query, il che ci porta alla conclusione: non dovremmo usare un singolo metodo per l'intero URI, perché non esiste una soluzione perfetta (finora). Come vedi &
non è stato eliminato da "Il mio blog e il tuo blog". Dobbiamo utilizzare una diversa forma di escape per i parametri della query, in cui gli utenti possono inserire caratteri diversi che hanno un significato speciale negli URL. Inserisci la codifica URL. La codifica URL deve essere utilizzata per ogni valore di query "sospetto", in modo simile a quanto ERB::Util.url_encode
segue:
ERB::Util.url_encode "My Blod & Your Blog"
# => "My%20Blod%20%26%20Your%20Blog""
È bello ma abbiamo già richiesto Indirizzabile:
uri = Addressable::URI.parse("http://www.go.com/foo")
# => #<Addressable::URI:0x186feb0 URI:http://www.go.com/foo>
uri.query_values = {title: "My Blog & Your Blog"}
uri.normalize.to_s
# => "http://www.go.com/foo?title=My%20Blog%20%26%20Your%20Blog"
Conclusione:
URI.escape
o similiCGI::escape
se è necessario solo il modulo di escapeAddressable
una delle tue gemme, puoi prima analizzare l'URL, fi rubydoc.info/gems/addressable/Addressable/URI.heuristic_parse
Addressable:URL
, è quindi possibile chiamare tutti i metodi di istanza su di esso, forse uno di loro ti darà i risultati desiderati: rubydoc.info/gems/addressable/Addressable/URI
URI.escape accetta un secondo parametro che ti consente di contrassegnare ciò che non è sicuro. Vedi APIDock:
CGI::escape
è utile per sfuggire al segmento di testo in modo che possano essere utilizzati nei parametri della query url (stringhe dopo '?'). Ad esempio, se si desidera avere un parametro contenente caratteri di barra nell'URL, è necessario prima CGI :: escape quella stringa e quindi inserirlo nell'URL.
Tuttavia in Rails probabilmente non lo utilizzerai direttamente. Di solito si utilizza hash.to_param
, che verrà utilizzato CGI::escape
sotto il cofano.
URI::escape
è buono per sfuggire a un URL che non è stato evaso correttamente. Ad esempio, alcuni siti Web generano URL errati / senza escape nel loro tag di ancoraggio. Se il tuo programma utilizza questi URL per recuperare più risorse, OpenURI si lamenterà che gli URL non sono validi. Hai bisogno di URI::escape
questi per renderlo un URL valido. Quindi viene utilizzato per sfuggire all'intera stringa URI per renderlo corretto. Nella mia parola URI :: unescape rende un url leggibile da umano e URI :: escape lo rende valido per i browser.
Questi sono i termini del mio profano e sono libero di correggerli.
La differenza è che URI.escape non funziona ...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
CGI.escape serve per sfuggire a un valore URL nella stringa di query. Tutti i personaggi che non rientrano in ALPHA, DIGIT, '_', '-', '.' e '' il set di caratteri è evaso.
Ma ciò renderebbe un URL errato, dal momento che un URL deve avere '/', ':', '?', '[', '&', '=', E ';'. Forse di più a cui non riesco a pensare dalla parte superiore della mia testa.
URI.escape lascia soli quei caratteri URL e cerca di scappare dalle chiavi e dai valori della stringa di query. Tuttavia, questo non può davvero dipendere dal fatto che i valori possono avere tutti i tipi di caratteri che impediscono una facile fuga. Fondamentalmente, è troppo tardi. Ma se si può fare affidamento sull'URL come semplice (nessun valore '&' e '=' ecc. Nei valori), questa funzione potrebbe essere utilizzata per sfuggire a caratteri forse illeggibili o illegali.
In generale, usa sempre CGI.escape sulle singole chiavi e valori prima di unirli con '&' e aggiungerli dopo '?'.
CGI.escape non ha funzionato con l'API OpenProject. Ha codificato il [] ,: e non il +. Ho hackerato questo insieme che sembra funzionare finora per l'API di OpenProject. Ma sono sicuro che manchi alcuni .gsub. Probabilmente è quasi cattivo come URI.escape, ma non ti darà gli errori obsoleti.
class XXX
def self.encode(path)
path, query = path.split("?", 2)
return path if query.nil?
query = CGI.escape(query).gsub("%3A", ":").gsub("%3D","=").gsub("%5B","[").gsub("%5D","]").gsub("%2C",",").gsub("+","%20")
return [path,query].join("?")
end
end
XXX.encode("http://test.com/some/path?query=[box: \"cart\"]")
URI.encode("http://test.com/some/path?query=[box: \"cart\"]")
Entrambe le uscite:
=> " http://test.com/some/path?query=[box:%20%22cart%22] "
=> " http://test.com/some/path?query=[box:%20 % 22cart% 22] "