Qual é a diferença entre URI.escape
e CGI.escape
e qual deles devo usar?
Qual é a diferença entre URI.escape
e CGI.escape
e qual deles devo usar?
Respostas:
Havia algumas pequenas diferenças, mas o ponto importante é que URI.escape
foi preterido no Ruby 1.9.2 ... então use CGI::escape
ou ERB :: Util.url_encode .
Há uma longa discussão sobre ruby-core para os interessados, que também menciona WEBrick :: HTTPUtils.escape e WEBrick :: HTTPUtils.escape_form .
ERB::Util.url_encode
que usa adequadamente %20
para espaços
Qual é a diferença entre um machado e uma espada e qual devo usar? Bem depende do que você precisa fazer.
URI.escape
deveria codificar uma string (URL) na chamada " codificação percentual " ".
CGI::escape
vem do CGI especificação , que descreve como os dados devem ser codificados / decodificados entre o servidor da Web e o aplicativo.
Agora, digamos que você precise escapar de um URI no seu aplicativo. É um caso de uso mais específico. Para isso, a comunidade Ruby usou URI.escape
por anos. O problema URI.escape
era que ele não conseguia lidar com as especificações 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
foi marcado como obsoleto:
Além disso, o URI.encode atual é simples gsub. Mas acho que ele deve dividir um URI em componentes, depois escapar de cada componente e finalmente se juntar a eles.
Portanto, o URI.encode atual é considerado prejudicial e descontinuado. Isso será removido ou mudará drasticamente o comportamento.
Qual é a substituição no momento?
Como eu disse acima, o URI.encode atual está errado no nível de especificação. Portanto, não forneceremos a substituição exata. A substituição variará de acordo com o caso de uso.
Infelizmente, não há uma única palavra sobre isso nos documentos, a única maneira de saber sobre isso é verificar a fonte ou executar o script com avisos no nível detalhado ( -wW2
) (ou usar algum google-fu).
Alguns propuseram usar CGI::Escape
para parâmetros de consulta, porque você não conseguiu escapar de um URI inteiro:
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
deve ser usado apenas para parâmetros de consulta, mas os resultados serão novamente contra as especificações. Na verdade, o caso de uso mais comum é o escape de dados do formulário, como ao enviar umapplication/x-www-form-urlencoded
solicitação POST.
Também mencionado WEBrick::HTTPUtils.escape
não há muita melhoria (novamente, é apenas uma opção simples gsub
, que é, na IMO, ainda pior do que 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"
O mais próximo da especificação parece ser a gema Endereçável :
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"
Observe que, ao contrário de todas as opções anteriores, o Endereçável não escapa #
e esse é o comportamento esperado. você deseja manter o #
hash no caminho do URI, mas não na consulta do URI.
O único problema que resta é que não escapamos adequadamente aos nossos parâmetros de consulta, o que nos leva à conclusão: não devemos usar um único método para todo o URI, porque não há solução perfeita (até agora). Como você vê, &
não escapou de "Meu Blog e Seu Blog". Precisamos usar uma forma diferente de escape para parâmetros de consulta, em que os usuários podem colocar caracteres diferentes que tenham um significado especial nos URLs. Digite a codificação de URL. A codificação de URL deve ser usada para cada valor de consulta "suspeito", semelhante ao que ERB::Util.url_encode
faz:
ERB::Util.url_encode "My Blod & Your Blog"
# => "My%20Blod%20%26%20Your%20Blog""
É legal, mas já exigimos Endereçável:
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"
Conclusão:
URI.escape
ou similarCGI::escape
se você precisar apenas de escape de formulárioAddressable
como uma das suas pedras preciosas, você pode analisar URL primeiro, fi rubydoc.info/gems/addressable/Addressable/URI.heuristic_parse
Addressable:URL
, você pode chamar todos os métodos de instância, talvez um deles obtenha os resultados desejados: rubydoc.info/gems/addressable/Addressable/URI
O URI.escape usa um segundo parâmetro que permite marcar o que não é seguro. Veja APIDock:
CGI::escape
é bom para escapar do segmento de texto para que eles possam ser usados nos parâmetros de consulta de URL (sequências após '?'). Por exemplo, se você deseja ter um parâmetro contendo caracteres de barra no URL, você CGI :: escapa a string primeiro e depois a insere no URL.
No entanto, no Rails, você provavelmente não o usará diretamente. Normalmente você usa hash.to_param
, o que usará CGI::escape
sob o capô.
URI::escape
é bom para escapar de um URL que não foi escapado corretamente. Por exemplo, alguns sites geram URLs incorretos / sem escape em sua tag de âncora. Se o seu programa usar esses URLs para buscar mais recursos, o OpenURI reclamará que os URLs são inválidos. Você precisa URI::escape
deles para torná-lo um URL válido. Portanto, é usado para escapar de toda a cadeia de URIs para torná-la adequada. Na minha palavra, o URI :: unescape torna um URL legível por humanos, e o URI :: escape o torna válido para os navegadores.
Estes são os termos do meu leigo e fique à vontade para corrigi-los.
A diferença é que o URI.escape não está funcionando ...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
CGI.escape é para escapar de um valor de URL na sequência de consultas. Todos os caracteres que não se enquadram no ALPHA, DIGIT, '_', '-', '.' e '' conjunto de caracteres são escapados.
Mas isso tornaria um URL incorreto, pois um URL precisa ter '/', ':', '?', '[', '&', '=' E ';'. Talvez mais do que eu possa imaginar.
O URI.escape deixa esses caracteres de URL em paz e tenta encontrar as chaves e os valores da string de consulta para escapar. No entanto, isso realmente não pode ser dependente, pois os valores podem ter todos os tipos de caracteres, impedindo uma fuga fácil. Basicamente, é tarde demais. Porém, se for possível confiar na URL como simples (sem '&' e '=' etc nos valores), essa função poderá ser usada para escapar de caracteres ilegíveis ou talvez ilegíveis.
Em geral - sempre use CGI.escape nas chaves e valores individuais antes de juntá-los a '&' e adicioná-los após o '?'.
CGI.escape não funcionou com a API do OpenProject. Codificou o [] ,: e não o +. Eu hackeei isso juntos, o que parece funcionar até agora para a API do OpenProject. Mas tenho certeza de que faltam alguns .gsub. Provavelmente é quase tão ruim quanto o URI.escape, mas não fornecerá erros obsoletos.
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\"]")
Ambas as saídas:
=> " http://test.com/some/path?query=[box:%20%22cart%22] "
=> " http://test.com/some/path?query=[box:%20 % 22art% 22] "