Hoe codeert u veilig een URL met JavaScript, zodat deze in een GET-tekenreeks kan worden geplaatst?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
Ik neem aan dat je de variabele myUrl
op die tweede regel moet coderen?
Antwoord 1, autoriteit 100%
Bekijk de ingebouwde functie encodeURIComponent(str )en encodeURI(str).
In jouw geval zou dit moeten werken:
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl);
Antwoord 2, autoriteit 54%
Je hebt drie opties:
-
escape()
codeert niet:@*/+
-
encodeURI()
codeert niet:~!@#$&*()=:/,;?+'
-
encodeURIComponent()
codeert niet:~!*()'
Maar in jouw geval, als je een URLwilt doorgeven aan een GET
parameter van een andere pagina, moet u escape
of encodeURIComponent
gebruiken, maar niet encodeURI
.
Zie Stack Overflow-vraag Best practice: escape, of encodeURI / encodeURIComponentvoor verdere discussie.
Antwoord 3, autoriteit 6%
Blijf bij encodeURIComponent()
. De functie encodeURI()
doet niet de moeite om veel tekens te coderen die semantisch belangrijk zijn in URL’s (bijv. “#”, “?” en “&”). escape()
is verouderd en doet niet de moeite om “+”-tekens te coderen, die zullen worden geïnterpreteerd als gecodeerde spaties op de server (en, zoals anderen hier aangeven, niet correct URL-coderen van niet-ASCII-tekens).
Er is een mooie uitleg van het verschil tussen encodeURI()
en encodeURIComponent()
elders. Als je iets wilt coderen zodat het veilig kan worden opgenomen als onderdeel van een URI (bijvoorbeeld als een queryreeksparameter), dan wil je encodeURIComponent()
gebruiken.
Antwoord 4, autoriteit 3%
Het beste antwoord is om encodeURIComponent
te gebruiken voor waardenin de queryreeks (en nergens anders).
Ik merk echter dat veel API’s ” ” willen vervangen door “+”, dus ik heb het volgende moeten gebruiken:
const value = encodeURIComponent(value).replace('%20','+');
const url = 'http://example.com?lang=en&key=' + value
escape
wordt in verschillende browsers anders geïmplementeerd en encodeURI
codeert niet veel tekens (zoals # en even /) — het is gemaakt om te worden gebruikt op een volledige URI /URL zonder het te breken wat niet super handig of veilig is.
En zoals @Jochem hieronder aangeeft, wil je misschien encodeURIComponent()
gebruiken voor een (elke) mapnaam, maar om welke reden dan ook lijken deze API’s +
in mapnamen, dus gewoon oud encodeURIComponent
werkt prima.
Voorbeeld:
const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;
Antwoord 5
Ik raad aan om het qs npm-pakket
te gebruiken
qs.stringify({a:"1=2", b:"Test 1"}); // gets a=1%3D2&b=Test+1
het is gemakkelijker te gebruiken met het JS-object en het geeft je de juiste URL-codering voor alle parameters
Als je jQuery gebruikt, zou ik gaan voor $.param
methode. De URL codeert een object dat velden toewijst aan waarden, wat gemakkelijker te lezen is dan het aanroepen van een escape-methode voor elke waarde.
$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1
Antwoord 6
encodeURIComponent() is de juiste keuze.
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
MAAR je moet er rekening mee houden dat er kleine verschillen zijn met de php-versie urlencode()
en zoals @CMS al zei, zal het niet elke char coderen. Jongens van http://phpjs.org/functions/urlencode/hebben js gelijk gemaakt aan 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', '+');
}
Antwoord 7
Om een URL te coderen, zoals eerder gezegd, heb je twee functies:
encodeURI()
en
encodeURIComponent()
De reden dat beide bestaan, is dat de eerste de URL bewaart met het risico dat er te veel dingen onbenut blijven, terwijl de tweede alles codeert wat nodig is.
Met de eerste zou je de zojuist ontsnapte URL naar de adresbalk kunnen kopiëren (bijvoorbeeld) en het zou werken. Maar uw ‘&’s zonder escapecodes zouden interfereren met veldscheidingstekens, de ‘=’s zouden interfereren met veldnamen en waarden, en de ‘+’s zouden eruitzien als spaties. Maar voor eenvoudige gegevens, wanneer u de URL-aard wilt behouden van wat u ontsnapt, werkt dit.
De tweede is alles wat u moet doen om ervoor te zorgen dat niets in uw tekenreeks een URL verstoort. Het laat verschillende onbelangrijke karakters niet ontsnappen, zodat de URL zo menselijk leesbaar mogelijk blijft zonder interferentie. Een URL die op deze manier is gecodeerd, werkt niet langer als een URL zonder deze te de-escaleren.
Dus als u de tijd kunt nemen, wilt u altijd encodeURIComponent() gebruiken — voordat u naam/waarde-paren toevoegt, codeert u zowel de naam als de waarde met deze functie voordat u deze aan de queryreeks toevoegt.
Ik vind het moeilijk om redenen te bedenken om de encodeURI() te gebruiken — dat laat ik aan de slimmere mensen over.
Antwoord 8
Moderne oplossing (2021)
Sinds de andere antwoorden zijn geschreven, zijn de URLSearchParamsAPI is geïntroduceerd. Het kan als volgt worden gebruikt:
const queryParams = { param1: 'value1', param2: 'value2' }
const queryString = new URLSearchParams(queryParams).toString()
Voor jouw specifieke voorbeeld zou je het als volgt gebruiken:
const myUrl = "http://example.com/index.html?param=1&anotherParam=2";
const myOtherUrl = "http://example.com/index.html";
myOtherUrl.search = new URLSearchParams({url: myUrl});
console.log(myOtherUrl.toString());
Deze oplossing wordt ook hieren hier.
Antwoord 9
Vergelijkbaar met wat ik heb geprobeerd met normaal javascript
function fixedEncodeURIComponent(str){
return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
Antwoord 10
Wat is URL-codering:
Een URL moet worden gecodeerd als er speciale tekens in de URL staan. Bijvoorbeeld:
console.log(encodeURIComponent('?notEncoded=&+'));
Antwoord 11
Om dubbele codering te voorkomen, is het een goed idee om de url te decoderen voordat u deze codeert (als u bijvoorbeeld te maken heeft met door de gebruiker ingevoerde URL’s, die mogelijk al zijn gecodeerd).
Laten we zeggen dat we abc%20xyz 123
als invoer hebben (één spatie is al gecodeerd):
encodeURI("abc%20xyz 123") // wrong: "abc%2520xyz%20123"
encodeURI(decodeURI("abc%20xyz 123")) // correct: "abc%20xyz%20123"
Antwoord 12
U mag encodeURIComponent()
niet rechtstreeks gebruiken.
Bekijk RFC3986: Uniform Resource Identifier (URI): Generic Syntax
subdelims = “!” / “$” / “&” / “‘” / “(” / “)”
/ “*” / “+” / “,” / “;” / “=”Het doel van gereserveerde tekens is om een reeks scheidingstekens te bieden die te onderscheiden zijn van andere gegevens binnen een URI.
Deze gereserveerde tekens uit de URI-definitie in RFC3986 WORDEN NIET ontsnapt door encodeURIComponent()
.
MDN-webdocumenten: encodeURIComponent()
Om strenger te zijn in het naleven van RFC 3986 (die !, ‘, (, ) en * voorbehoudt), hoewel deze tekens geen geformaliseerde URI-afbakening hebben, kan het volgende veilig worden gebruikt:
Gebruik de MDN Web Docs-functie…
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
Antwoord 13
Niets werkte voor mij. Het enige wat ik zag was de HTML van de inlogpagina, die terugkwam naar de clientzijde met code 200. (302 in eerste instantie maar hetzelfde Ajax-verzoek om de inlogpagina te laden in een ander Ajax-verzoek, dat een omleiding moest zijn in plaats van gewoon te laden tekst van de inlogpagina).
In de login-controller heb ik deze regel toegevoegd:
Response.Headers["land"] = "login";
En in de globale Ajax-handler deed ik dit:
$(function () {
var $document = $(document);
$document.ajaxSuccess(function (e, response, request) {
var land = response.getResponseHeader('land');
var redrUrl = '/login?ReturnUrl=' + encodeURIComponent(window.location);
if(land) {
if (land.toString() === 'login') {
window.location = redrUrl;
}
}
});
});
Nu heb ik geen enkel probleem, en het werkt als een tierelier.
Antwoord 14
URL-tekenreeks coderen
var url = $(locatie).attr('href'); // haal de huidige url op
//OF
var url = 'map/index.html?param=#23dd&noob=ja'; //of specificeer er een
var encodedUrl = encodeURIComponent(url);
console.log(encodedUrl);
//outputs folder%2Findex.html%3Fparam%3D%2323dd%26noob%3Dyes
for more info go http://www.sitepoint.com/jquery-decode-url-string
Antwoord 15
Hier is een LIVE DEMOvan encodeURIComponent()
en decodeURIComponent()
JS ingebouwde functies:
<!DOCTYPE html>
<html>
<head>
<style>
textarea{
width:30%;
height:100px;
}
</style>
<script>
// encode string to base64
function encode()
{
var txt = document.getElementById("txt1").value;
var result = btoa(txt);
document.getElementById("txt2").value = result;
}
// decode base64 back to original string
function decode()
{
var txt = document.getElementById("txt3").value;
var result = atob(txt);
document.getElementById("txt4").value = result;
}
</script>
</head>
<body>
<div>
<textarea id="txt1">Some text to decode
</textarea>
</div>
<div>
<input type="button" id="btnencode" value="Encode" onClick="encode()"/>
</div>
<div>
<textarea id="txt2">
</textarea>
</div>
<br/>
<div>
<textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
</textarea>
</div>
<div>
<input type="button" id="btndecode" value="Decode" onClick="decode()"/>
</div>
<div>
<textarea id="txt4">
</textarea>
</div>
</body>
</html>
Antwoord 16
U kunt de esapi-bibliotheek gebruiken en uw url coderen met de onderstaande functie. De functie zorgt ervoor dat ‘/’ niet verloren gaat door codering, terwijl de rest van de tekstinhoud wordt gecodeerd:
function encodeUrl(url)
{
String arr[] = url.split("/");
String encodedUrl = "";
for(int i = 0; i<arr.length; i++)
{
encodedUrl = encodedUrl + ESAPI.encoder().encodeForHTML(ESAPI.encoder().encodeForURL(arr[i]));
if(i<arr.length-1) encodedUrl = encodedUrl + "/";
}
return url;
}
https://www.owasp.org/index.php/ESAPI_JavaScript_Readme
Antwoord 17
Gebruik de functie fixedEncodeURIComponent
om strikt te voldoen aan RFC 3986:
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
Antwoord 18
Prestaties
Vandaag (2020.06.12) voer ik een snelheidstest uit voor gekozen oplossingen op MacOs HighSierra 10.13.6 in browsers Chrome 83.0, Safari 13.1, Firefox 77.0. Deze resultaten kunnen handig zijn voor het coderen van massale URL’s.
Conclusies
encodeURI
(B) lijkt de snelste te zijn, maar wordt niet aanbevolen voor url-sescape
(A) is een snelle oplossing voor meerdere browsers- oplossing F aanbevolen door MDNis gemiddeld snel
- oplossing D is het langzaamst
Details
Voor oplossingen
A
B
C
D
E
F
Ik voer twee tests uit
- voor korte url – 50 tekens – u kunt het HIER
- voor lange url – 1M char – kun je het HIER
uitvoeren
uitvoeren
Antwoord 19
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl).replace(/%20/g,'+');
Vergeet de vlag /g niet om alle gecodeerde ‘ ‘
. te vervangen
Antwoord 20
Ik denk dat je nu in 2021, om echt veilig te zijn, altijd moet overwegen om je URL’s samen te stellen met URL()
-interface. Het zal het meeste werk voor je doen. Dus kom naar je code,
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
const params = new URLSearchParams(myOtherUrl.search);
console.log(params.get('url')); // Outputs: http://example.com/index.html?param=1&anotherParam=2
Zoiets zal zeker niet mislukken.
Antwoord 21
Ik gebruik dit altijd om dingen voor URL’s te coderen. Dit is volkomen veilig omdat het elk afzonderlijk teken zal coderen, zelfs als het niet gecodeerd hoeft te worden.
function urlEncode(text) {
let encoded = '';
for (let char of text) {
encoded += '%' + char.charCodeAt(0).toString(16);
}
return encoded;
}