Como codificar parâmetros de URL?

123

Estou tentando passar parâmetros para um URL parecido com este:

http://www.foobar.com/foo?imageurl=

E eu quero passar os parâmetros como um URL de imagem que é gerado por outra API, e o link para a imagem fica assim:

http://www.image.com/?username=unknown&password=unknown

No entanto, quando tento usar o URL:

http://www.foobar.com/foo?imageurl=http://www.image.com/?username=unknown&password=unknown

Não funciona.

Também tentei usar encodeURI()e encodeURIComponent()no imageURL, mas também não funcionou.

Apoorv Saxena
fonte
Qual idioma está gerando o URL? JavaScript?
Phil
2
Observe que você não deve colocar senhas em urls, nem mesmo ao usar https, pois todo roteador entre cliente e servidor verá a url inteira.
fabb

Respostas:

171

Com PHP

echo urlencode("http://www.image.com/?username=unknown&password=unknown");

Resultado

http%3A%2F%2Fwww.image.com%2F%3Fusername%3Dunknown%26password%3Dunknown

Com Javascript:

var myUrl = "http://www.image.com/?username=unknown&password=unknown";
var encodedURL= "http://www.foobar.com/foo?imageurl=" + encodeURIComponent(myUrl);

DEMO: http://jsfiddle.net/Lpv53/

Niels
fonte
37

Usando o novo ES6 Object.entries(), torna-se um pouco divertido aninhado map/ join:

const encodeGetParams = p => 
  Object.entries(p).map(kv => kv.map(encodeURIComponent).join("=")).join("&");

const params = {
  user: "María Rodríguez",
  awesome: true,
  awesomeness: 64,
  "ZOMG+&=*(": "*^%*GMOZ"
};

console.log("https://example.com/endpoint?" + encodeGetParams(params))

Kyle VanderBeek
fonte
1

Você não deve usar encodeURIComponent()ou encodeURI(). Você deve usar fixedEncodeURIComponent()e fixedEncodeURI(), de acordo com a Documentação MDN.

Em relação encodeURI()...

Se alguém deseja seguir o RFC3986 mais recente para URLs, que torna os colchetes reservados (para IPv6) e, portanto, não codificados ao formar algo que poderia ser parte de um URL (como um host), o seguinte snippet de código pode ajudar:

function fixedEncodeURI(str) { return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']'); }

Em relação encodeURIComponent()...

Para ser mais rigoroso na adesão ao RFC 3986 (que reserva!, ', (,) E *), embora esses caracteres não tenham usos de delimitação de URI formalizados, o seguinte pode ser usado com segurança:

function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }

Então qual é a diferença? fixedEncodeURI()e fixedEncodeURIComponent()converter o mesmo conjunto de valores, mas fixedEncodeURIComponent()também converte este conjunto: +@?=:*#;,$&. Este conjunto é utilizado em GETparâmetros ( &, +, etc.), marcas de âncora ( #), etiquetas curinga ( *), peças de e-mail / nome de usuário ( @), etc ..

Por exemplo - Se você usar encodeURI(), [email protected]/?email=me@homenão enviará corretamente o segundo @para o servidor, exceto para o seu navegador lidar com a compatibilidade (como o Chrome naturalmente faz com frequência).

HoldOffHunger
fonte
O que você quer dizer com "except for your browser handling the compatibility"?
Stephan
@Stephan: Por exemplo, se site.com?formula=a+b=ctrabalha na produção formula=>a+b=c, isso viola as especificações, mas se funciona, é porque Chrome / etc. pode detectar a falha de especificação do URL, etc., e assim por diante, w / [email protected][email protected].
HoldOffHunger