如何使用JavaScript安全地编码URL,以便可以将其放入GET字符串中?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
我假设您需要myUrl
在第二行编码该变量?
如何使用JavaScript安全地编码URL,以便可以将其放入GET字符串中?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
我假设您需要myUrl
在第二行编码该变量?
Answers:
签出内置函数encodeURIComponent(str)和encodeURI(str)。
在您的情况下,这应该起作用:
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl);
escape
也是有效的选择。
encodeURI
,URL编码并不是很安全。
:
,/
,@
等不使用可互换的这2种方法,你必须知道你的编码使用正确的方法是什么。
您有三种选择:
escape()
将不会编码: @*/+
encodeURI()
将不会编码: ~!@#$&*()=:/,;?+'
encodeURIComponent()
将不会编码: ~!*()'
但在您的情况下,如果要将URL传递到GET
其他页面的参数中,则应使用escape
或encodeURIComponent
,但不能使用encodeURI
。
有关进一步的讨论,请参见堆栈溢出问题最佳实践:转义,或encodeURI / encodeURIComponent。
%uxxx
。
坚持下去encodeURIComponent()
。该函数encodeURI()
不会麻烦编码许多在URL中具有语义重要性的字符(例如“#”,“?”和“&”)。escape()
已弃用,并且不会费心地对“ +”字符进行编码,后者将被解释为服务器上的编码空格(并且,如此处其他人所指出的那样,不会正确地对非ASCII字符进行URL编码)。
有一个很好的区别的解释encodeURI()
和encodeURIComponent()
其他地方。如果您希望对某些内容进行编码,以便可以安全地将其作为URI的组成部分(例如,作为查询字符串参数),请使用encodeURIComponent()
。
最好的答案是使用encodeURIComponent
上值的查询字符串(和其他地方)。
但是,我发现许多API都希望将“”替换为“ +”,因此我不得不使用以下内容:
const value = encodeURIComponent(value).replace('%20','+');
const url = 'http://example.com?lang=en&key=' + value
escape
在不同的浏览器中以不同的方式实现,encodeURI
并且不对许多字符进行编码(例如#甚至是/)-使其用于完整的URI / URL而不会破坏它-这不是超级有用或安全的做法。
就像@Jochem在下面指出的那样,您可能想encodeURIComponent()
在一个(每个)文件夹名称上使用,但是由于任何原因,这些API似乎都不希望+
在文件夹名称中使用,所以普通的旧版本encodeURIComponent
效果很好。
例:
const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;
http://somedomain/this dir has spaces/info.php?a=this has also spaces
。应该将其转换为:http://somedomain/this%20dir%20has%spaces/info.php?a=this%20has%20also%20spaces
但是许多实现允许将查询字符串中的'%20'替换为'+'。但是,您不能在URL的路径部分中将“%20”替换为“ +”,这将导致未找到错误,除非您的目录中带有+
而不是空格。
encodeURIComponent('+')
是%2B
,@ njzk2 会给你,所以你必须使用两个正则表达式...我想这是为什么这样起作用的原因,因为最后的'+'是''编码不同。
如果您使用的是jQuery,我将寻求$.param
方法。它使用URL编码将对象映射到值的对象,这比在每个值上调用转义方法更容易阅读。
$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1
encodeURIComponent()是必经之路。
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
但是您应该记住,与php版本有一些细微的区别urlencode()
,正如@CMS所提到的,它不会对每个字符进行编码。http://phpjs.org/functions/urlencode/的家伙将js等效于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', '+');
}
如前所述,要对URL进行编码,您有两个功能:
encodeURI()
和
encodeURIComponent()
两者都存在的原因是,第一个保留了URL,却有使太多内容无法逃脱的风险,而第二个则编码了所需的所有内容。
对于第一个,您可以将新转义的URL复制到地址栏中(例如),它可以工作。但是,未转义的“&”会干扰字段定界符,“ =”会干扰字段名和值,而“ +”则看起来像空格。但是对于简单数据,当您想要保留要转义的URL的本性时,此方法有效。
第二个是您需要做的所有事情,以确保字符串中的任何内容都不会干扰URL。它保留了各种不重要的字符,从而使URL尽可能保持人类可读性,而不会受到干扰。如果不进行转义,则以这种方式编码的URL将不再用作URL。
因此,如果可以的话,您总是想使用encodeURIComponent()-在添加名称/值对之前,使用此函数对名称和值进行编码,然后再将其添加到查询字符串中。
我在艰难时期想出使用encodeURI()的理由-我会将其留给聪明的人。
我尝试使用普通javascript进行的类似操作
function fixedEncodeURIComponent(str){
return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
以我的拙见,对查询参数进行编码的最优雅的方法是创建一个具有以下参数的对象
const queryParams = { param1: 'value1', param2: 'value2' }
然后使用以下代码对其进行编码:
const queryString = new URLSearchParams(queryParams).toString()
如此答案中所述:https : //stackoverflow.com/a/53171438/7284582
如果网址中包含特殊字符,则应对网址进行编码。例如:
console.log(encodeURIComponent('?notEncoded=&+'));
在此示例中,我们可以观察到,除字符串以外的所有字符notEncoded
都使用%符号编码。URL编码也称为百分比编码,因为它会用%转义所有特殊字符。然后,在此%符号后,每个特殊字符都有一个唯一的代码
某些字符在URL字符串中具有特殊值。例如,?字符表示查询字符串的开头。为了成功地在Web上定位资源,必须区分字符是字符串的一部分还是url结构的一部分。
JS提供了一堆内置实用程序功能,我们可以使用它们轻松地对URL进行编码。这是两个方便的选项:
encodeURIComponent()
:以URI的组成部分作为参数,并返回已编码的URI字符串。encodeURI()
:以URI作为参数并返回编码的URI字符串。请注意不要将整个URL(包括方案,例如https://)传递到中encodeURIComponent()
。实际上,这可以将其转换为无法正常使用的URL。例如:
// 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"));
我们可以观察到如果我们将整个URL放入 encodeURIComponent
,则前斜杠(/)也将转换为特殊字符。这将导致URL无法正常运行。
因此(顾名思义)使用:
encodeURIComponent
在您要编码的URL的特定部分上。encodeURI
在您要编码的整个URL上。什么都没有为我工作。我所看到的只是登录页面的HTML,它返回到客户端,代码为200。(最初是302,但同一Ajax请求将登录页面加载到另一个Ajax请求中,这应该是重定向而不是简单地加载登录页面的文本)。
在登录控制器中,我添加了以下行:
Response.Headers["land"] = "login";
在全局Ajax处理程序中,我这样做:
$(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;
}
}
});
});
现在,我没有任何问题,它就像一个护身符。
编码URL字符串
var url = $ (位置)。attr ('href' ); //获取当前网址// OR var url = 'folder / index.html?param =#23dd&noob = yes' ; //或指定一个
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
这里有一个现场演示的encodeURIComponent()
和decodeURIComponent()
内置函数JS:
<!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>
您可以使用esapi库并使用以下功能对url进行编码。该函数确保在编码其余文本内容时不会丢失“ /”以进行编码:
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;
}
您不应该encodeURIComponent()
直接使用。
sub-delims =“!” /“ $” /“&” /“'” /“(” /“)” /“ *” /“ +” /“,” /“;” /“ =”
保留字符的目的是提供一组与URI中的其他数据区分开的定界字符。
RFC3986中URI定义中的这些保留字符不会被逸出encodeURIComponent()
。
MDN Web文档:encodeURIComponent()
为了严格遵守RFC 3986(保留!,',(,)和*),即使这些字符没有正式的URI分隔用法,也可以安全地使用以下字符:
使用MDN Web文档功能...
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}