如何使用JavaScript安全地编码URL,以便将其放入GET字符串中?

var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;

我假设您需要在第二行编码myUrl变量?


当前回答

表演

今天(2020.06.12),我在浏览器Chrome 83.0、Safari 13.1和Firefox 77.0的macOS v10.13.6(High Sierra)上对所选解决方案进行了速度测试。这一结果对于大规模URL编码非常有用。

结论

encodeURI(B)似乎最快,但不建议用于URLescape(A)是一种快速的跨浏览器解决方案MDN推荐的解决方案F为中速解决方案D最慢

细节

对于解决方案A.BCDEF我进行了两次测试

对于短URL-50个字符-您可以在这里运行对于长URL-1M个字符-您可以在此处运行

函数A(url){返回转义符(url);}函数B(url){返回encodeURI(url);}函数C(url){返回encodeURIComponent(url);}函数D(url){返回新的URLSearchParams({url}).toString();}函数E(url){return encodeURIComponent(url).replace(/[!'()]/g,escape).replace(/\*/g,“%2A”);}函数F(url){return encodeURIComponent(url).replace(/[!'()*]/g,函数(c){return“%”+c.charCodeAt(0).toString(16);});}// ----------//测试// ----------var myUrl=“http://example.com/index.html?param=1&anotherParam=2";[A、B、C、D、E、F].forEach(f=>console.log(`${f.name}?url=${f(myUrl).replace(/^url=/,'')}`));此代码段仅显示所选解决方案的代码

Chrome的示例结果

其他回答

我用普通JavaScript做了类似的尝试:

function fixedEncodeURIComponent(str){
    return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}

您有三个选项:

escape()不会编码:@*/+encodeURI()不会编码:~@#$&*()=:/,;?+'encodeURIComponent()不会编码:~*()'

但在您的情况下,如果要将URL传递到其他页面的GET参数中,则应该使用escape或encodeURIComponent,而不是encodeURI。

有关详细讨论,请参阅堆栈溢出问题最佳实践:转义或encodeURI/encodeURIComponent。

这里是encodeURIComponent()和decodeURIComponent()JavaScript内置函数的现场演示:

<!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>

查看内置函数encodeURIComponent(str)和encodeURI(str)。在您的情况下,这应该有效:

var myOtherUrl = 
       "http://example.com/index.html?url=" + encodeURIComponent(myUrl);

我总是用这个来编码URL。这是完全安全的,因为它将对每个字符进行编码,即使它不必进行编码。

function urlEncode(text) {
    let encoded = '';
    for (let char of text) {
        encoded += '%' + char.charCodeAt(0).toString(16);
    }
    return encoded;
}