Koda URL i JavaScript
Hur kodar man en URL säkert med JavaScript så att den kan sättas in i en GET-sträng?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
Jag antar att du behöver koda myUrl-variabeln på den andra raden?
Svar #1
Kolla på den inbyggda funktionen encodeURIComponent(str) och encodeURI(str).
I ditt fall borde detta fungera:
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl);
Svar #2
Du har tre alternativ:
escape()kommer inte att koda:@*/+encodeURI()kommer inte att koda:~!@#$&*()=:/,;?+'encodeURIComponent()kommer inte att koda:~!*()'
Men i ditt fall, om du vill skicka en URL till en GET-parameter på en annan sida, bör du använda escape eller encodeURIComponent, men inte encodeURI.
Se Stack Overflow-frågan Best practice: escape, or encodeURI/encodeURIComponent för vidare diskussion.
Svar #3
Håll dig till encodeURIComponent(). Funktionen encodeURI() bryr sig inte om att koda många tecken som har semantisk betydelse i URL:er (t.ex. "#", "?" och "&"). escape() är föråldrad och bryr sig inte om att koda '+'-tecken, som kommer att tolkas som kodade mellanslag på servern (och, som andra här har påpekat, kodar inte icke-ASCII-tecken korrekt för URL).
Det finns en bra förklaring av skillnaden mellan encodeURI() och encodeURIComponent() någon annanstans. Om du vill koda något så att det kan inkluderas säkert som en del av en URI (t.ex. som en parameter i en frågesträng) vill du använda encodeURIComponent().
Svar #4
Det bästa svaret är att använda encodeURIComponent på värden i frågesträngen (och ingen annanstans).
Men jag upptäcker att många äldre API:er vill ersätta " " med "+" så jag har varit tvungen att använda följande:
const value = encodeURIComponent(value).replaceAll('%20','+');
const url = 'http://example.com?lang=en&key=' + value
escape implementeras olika i olika webbläsare och encodeURI kodar inte många tecken (som # och till och med /) - det är gjort för att användas på en full URI/URL utan att bryta den - vilket inte är särskilt hjälpsamt eller säkert.
Och som @Jochem påpekar nedan, kanske du vill använda encodeURIComponent() på ett (varje) mappnamn, men av någon anledning verkar dessa API:er inte vilja ha + i mappnamn, så vanliga encodeURIComponent fungerar utmärkt.
Exempel :
const escapedValue = encodeURIComponent(value).replaceAll('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;
Svar #5
Modern lösning (2021)
Sedan de andra svaren skrevs har URLSearchParams API introducerats. Det kan användas så här:
const queryParams = { param1: 'value1', param2: 'value2' }
const queryString = new URLSearchParams(queryParams).toString()
// 'param1=value1¶m2=value2'
Det kodar också icke-URL-tecken.
För ditt specifika exempel skulle du använda det så här:
const myUrl = "http://example.com/index.html?param=1&anotherParam=2"; const myOtherUrl = new URL("http://example.com/index.html"); myOtherUrl.search = new URLSearchParams({url: myUrl}); console.log(myOtherUrl.toString());
Denna lösning nämns också här och här.
Svar #6
Jag skulle föreslå att använda qs npm-paketet:
qs.stringify({a:"1=2", b:"Test 1"}); // gets a=1%3D2&b=Test+1
Det är lättare att använda med ett JavaScript-objekt och det ger dig korrekt URL-kodning för alla parametrar.
Om du använder jQuery skulle jag välja $.param-metoden. Den URL-kodar ett objekt, och mappar fält till värden, vilket är lättare att läsa än att anropa en escape-metod på varje värde.
$.param({a:"1=2", b:"Test 1"}) // Gets a=1%3D2&b=Test+1
Svar #7
Jag tycker att man nu år 2022 för att vara riktigt säker alltid bör överväga att konstruera sina URL:er med URL()-gränssnittet. Det kommer att göra det mesta av jobbet åt dig. Så när det gäller din kod,
const baseURL = 'http://example.com/index.html';
const myUrl = new URL(baseURL);
myUrl.searchParams.append('param', '1');
myUrl.searchParams.append('anotherParam', '2');
const myOtherUrl = new URL(baseURL);
myOtherUrl.searchParams.append('url', myUrl.href);
console.log(myUrl.href);
// Outputs: http://example.com/index.html?param=1&anotherParam=2
console.log(myOtherUrl.href);
// Outputs: http://example.com/index.html?url=http%3A%2F%2Fexample.com%2Findex.html%3Fparam%3D1%26anotherParam%3D2
console.log(myOtherUrl.searchParams.get('url'));
// Outputs: http://example.com/index.html?param=1&anotherParam=2Eller...
const params = new URLSearchParams(myOtherUrl.search);
console.log(params.get('url'));
// Outputs: http://example.com/index.html?param=1&anotherParam=2
Något liknande detta är garanterat att inte misslyckas.
Svar #8
encodeURIComponent() är vägen att gå.
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
Men du bör komma ihåg att det finns små skillnader från PHP-versionen urlencode() och som @CMS nämnde, kommer den inte att koda varje tecken. Killarna på http://phpjs.org/functions/urlencode/ gjorde en JavaScript-ekvivalent till phpencode():
function urlencode(str) {
str = (str + '').toString();
// Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
// PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
return encodeURIComponent(str)
.replace('!', '%21')
.replace('\'', '%27')
.replace('(', '%28')
.replace(')', '%29')
.replace('*', '%2A')
.replace('%20', '+');
}
Svar #9
För att koda en URL, som tidigare har sagts, har du två funktioner:
encodeURI()
och
encodeURIComponent()
Anledningen till att båda existerar är att den första bevarar URL:en med risken att lämna för många saker oekade, medan den andra kodar allt som behövs.
Med den första kunde du kopiera den nyligen undkomna URL:en till adressfältet (till exempel) och det skulle fungera. Däremot skulle dina icke-undkomna '&' störa fältdelare, '=' skulle störa fältnamn och värden, och '+' skulle se ut som mellanslag. Men för enkel data när du vill bevara URL-karaktären hos det du undkommer, fungerar detta.
Den andra är allt du behöver göra för att se till att inget i din sträng stör en URL. Den lämnar olika oviktiga tecken oescapade så att URL:en förblir så läsbar som möjligt för människor utan störningar. En URL som är kodad på detta sätt kommer inte längre att fungera som en URL utan att den escapas upp.
Så om du kan ta dig tid, vill du alltid använda encodeURIComponent() -- innan du lägger till namn/värde-par, koda både namnet och värdet med denna funktion innan du lägger till det i frågesträngen.
Jag har svårt att komma på anledningar att använda encodeURI() -- jag lämnar det till de smartare människorna.
Svar #10
Vad är URL-kodning:
En URL bör kodas när det finns specialtecken i URL:en. Till exempel:
console.log(encodeURIComponent('?notEncoded=&+'));Vi kan observera i detta exempel att alla tecken förutom strängen notEncoded är kodade med %-tecken. URL-kodning är också känt som procentkodning eftersom det flyr alla specialtecken med ett %. Sedan, efter detta % -tecken, har varje specialtecken en unik kod
Varför behöver vi URL-kodning:
Vissa tecken har ett speciellt värde i en URL-sträng. Till exempel betecknar tecknet ? början på en frågesträng. För att framgångsrikt kunna lokalisera en resurs på webben är det nödvändigt att skilja på när ett tecken är avsett som en del av strängen eller som en del av URL-strukturen.
Hur kan vi uppnå URL-kodning i JavaScript:
JavaScript erbjuder en mängd inbyggda hjälpfunktioner som vi kan använda för att enkelt koda URL:er. Här är två praktiska alternativ:
encodeURIComponent(): Tar en komponent av en URI som argument och returnerar den kodade URI-strängen.encodeURI(): Tar en URI som argument och returnerar den kodade URI-strängen.
Exempel och varningar:
Var medveten om att inte skicka in hela URL:en (inklusive schema, t.ex. https://) i encodeURIComponent(). Detta kan faktiskt göra att den blir en icke fungerande URL. Till exempel:
// for a whole URI don't use encodeURIComponent it will transform
// the / characters and the URL won't fucntion properly
console.log(encodeURIComponent("http://www.random.com/specials&char.html"));
// instead use encodeURI for whole URL's
console.log(encodeURI("http://www.random.com/specials&char.html"));Vi kan observera att om vi sätter hela URL:en i encodeURIComponent så omvandlas även snedstrecken (/) till specialtecken. Detta kommer att göra att URL:en inte fungerar korrekt längre.
Därför (som namnet antyder) använd:
encodeURIComponentpå en viss del av en URL som du vill koda.encodeURIpå en hel URL som du vill koda.
