URL coderen in JavaScript?

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 myUrlop 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: [email protected]#$&*()=:/,;?+'

  • encodeURIComponent()codeert niet: ~!*()'

Maar in jouw geval, als je een URLwilt doorgeven aan een GETparameter van een andere pagina, moet u escapeof encodeURIComponentgebruiken, 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 encodeURIComponentte 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

escapewordt in verschillende browsers anders geïmplementeerd en encodeURIcodeert 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 encodeURIComponentwerkt 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 $.parammethode. 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 123als 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 fixedEncodeURIComponentom 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-s
  • escape(A) is een snelle oplossing voor meerdere browsers
  • oplossing F aanbevolen door MDNis gemiddeld snel
  • oplossing D is het langzaamst

voer hier de afbeeldingsbeschrijving in

Details

Voor oplossingen
A
B
C
D
E
F
Ik voer twee tests uit

  • voor korte url – 50 tekens – u kunt het HIER
  • uitvoeren

  • voor lange url – 1M char – kun je het HIER
  • 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;
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes