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

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

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


当前回答

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

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

其他回答

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

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

您有三个选项:

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

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

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

现代解决方案(2021)

自从编写了其他答案后,就引入了URLSearchParams API。它可以这样使用:

const queryParams = { param1: 'value1', param2: 'value2' }
const queryString = new URLSearchParams(queryParams).toString()
// 'param1=value1&param2=value2'

它还编码非URL字符。

对于您的具体示例,您可以这样使用:

常量myUrl=“http://example.com/index.html?param=1&anotherParam=2";const myOtherUrl=新URL(“http://example.com/index.html");myOtherUrl.search=新URLSearchParams({url:myUrl});console.log(myOtherUrl.toString());

这个解决方案也在这里和这里提到。

最好的答案是对查询字符串中的值使用encodeURIComponent(而不是其他)。

然而,我发现许多API都想用“+”替换“”,所以我不得不使用以下方法:

const value = encodeURIComponent(value).replace('%20','+');
const url = 'http://example.com?lang=en&key=' + value

escape在不同浏览器中的实现方式不同,encodeURI不编码许多字符(如#和甚至/)——它可以在完整的URI/URL上使用,而不会破坏它——这并不是非常有用或安全的。

正如@Jochem在下面指出的,您可能希望在(每个)文件夹名称上使用encodeURIComponent(),但无论出于什么原因,这些API似乎不希望在文件夹名称中使用+,所以普通的encodeURIComponents非常有用。

例子:

const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;

表演

今天(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的示例结果