mat*_*e64 25 javascript url location href
什么是最快的方法来检测是否foo='http://john.doe'是外部URL(与之相比window.location.href)?
Gum*_*mbo 32
如果您认为URL是外部的,如果方案,主机或端口不同,您可以执行以下操作:
function isExternal(url) {
var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) return true;
if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"), "") !== location.host) return true;
return false;
}
Run Code Online (Sandbox Code Playgroud)
pse*_*ant 17
我知道正则表达式版本已被接受,但我敢打赌这比正则表达式的复杂性"更快".String.replace很快.
var isExternal = function(url) {
var domain = function(url) {
return url.replace('http://','').replace('https://','').split('/')[0];
};
return domain(location.href) !== domain(url);
}
Run Code Online (Sandbox Code Playgroud)
我决定对此进行更多的研究,并找到了一种使用正则表达式的更快的方法.
var isExternalRegexClosure = (function(){
var domainRe = /https?:\/\/((?:[\w\d-]+\.)+[\w\d]{2,})/i;
return function(url) {
function domain(url) {
return domainRe.exec(url)[1];
}
return domain(location.href) !== domain(url);
}
})();
Run Code Online (Sandbox Code Playgroud)
在IE中,这比String.replace方法稍快.但是在Chrome和Firefox中它的速度大约是其两倍.此外,在封闭内部仅定义一次Regex而不是仅仅在函数内部通常在Firefox中快30%左右.
这是一个jsperf,它检查了确定外部主机名的四种不同方法.
重要的是要注意,即使在旧手机上,我尝试过的每种方法都需要不到1毫秒的时间.因此,除非您正在进行大批量处理,否则性能可能不应该是您的主要考虑因素.
shs*_*haw 16
我一直在使用psuedosavant的方法,但遇到了一些触发误报的情况,例如无域链接(/about,image.jpg)和锚链接(#about).旧方法也会为不同的协议(httpvs https)提供不准确的结果.
这是我的略微修改版本:
var checkDomain = function(url) {
if ( url.indexOf('//') === 0 ) { url = location.protocol + url; }
return url.toLowerCase().replace(/([a-z])?:\/\//,'$1').split('/')[0];
};
var isExternal = function(url) {
return ( ( url.indexOf(':') > -1 || url.indexOf('//') > -1 ) && checkDomain(location.href) !== checkDomain(url) );
};
Run Code Online (Sandbox Code Playgroud)
以下是一些更新功能的测试:
isExternal('http://google.com'); // true
isExternal('https://google.com'); // true
isExternal('//google.com'); // true (no protocol)
isExternal('mailto:mail@example.com'); // true
isExternal('http://samedomain.com:8080/port'); // true (same domain, different port)
isExternal('https://samedomain.com/secure'); // true (same domain, https)
isExternal('http://samedomain.com/about'); // false (same domain, different page)
isExternal('HTTP://SAMEDOMAIN.COM/about'); // false (same domain, but different casing)
isExternal('//samedomain.com/about'); // false (same domain, no protocol)
isExternal('/about'); // false
isExternal('image.jpg'); // false
isExternal('#anchor'); // false
Run Code Online (Sandbox Code Playgroud)
根据一些基本的jsperf测试,它总体来说更准确,甚至最终会略微加快.如果您.toLowerCase()不进行不区分大小写的测试,则可以进一步加快速度.