检测外部URL的最快方法
检测if检测外部URL的最快方法,url,javascript,location,href,Url,Javascript,Location,Href,检测iffoo=”的最快方法是什么http://john.doe“是外部的(与window.location.href相比)=3){ //查看第二级域是否为普通SLD。 如果(部分[1]。匹配(/^(com | edu | gov | net | mil | org | nom | co | name | info | biz)$/i)){ 退货零件[2]+'.+零件[1]+'.+零件[0]; } } 返回零件[1]+'.+零件[0]; }; var isexternalur=函数(url){
foo=”的最快方法是什么http://john.doe“
是外部的(与window.location.href
相比)如果你认为一个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;
}
更新:我做了更多的研究,发现使用
新URL
实际上是最快的,也是最直接的方法
重要的是要注意,我尝试过的每种方法即使在旧手机上运行也不到1ms。因此,性能可能不应该是您的主要考虑因素,除非您正在进行一些大批量处理
以下是我尝试过的三种方法:
新URL
:
函数isExternalURL(url){
返回新URL(URL).origin!==location.origin;
}
String.replace:
函数isExternalReplace(url){
变量域=函数(url){
返回url.replace('http://','').replace('https://','').split('/')[0];
};
返回域(location.href)!==域(url);
}
正则表达式:
常量isExternalRegex=(函数(){
var-domainRe=/https?:\/\/((?:[\w\d-]+\)+[\w\d]{2,})/i;
返回函数(url){
功能域(url){
返回domainRe.exec(url)[1];
}
返回域(location.href)!==域(url);
}
})();
下面是我用来测试性能的一些基本测试:pseudosavant的答案对我来说不太合适,所以我改进了它
var isExternal = function(url) {
return !(location.href.replace("http://", "").replace("https://", "").split("/")[0] === url.replace("http://", "").replace("https://", "").split("/")[0]);
}
我一直在使用psuedsavant的方法,但遇到了一些触发误报的情况,例如无域链接(
/about
,image.jpg
)和锚链接(#about
)。旧方法也会对不同的协议给出不准确的结果(http
vshttps
)
这是我稍微修改过的版本:
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) );
};
以下是一些使用更新功能的测试:
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
根据一些基本的理论,它总体上更准确,甚至速度也稍微快了一点。如果不使用
.toLowerCase()
进行不区分大小写的测试,可以加快测试速度。我必须基于pseudosavant和Jon的答案,因为我还需要捕获以“/”开头的URL和不包含子域的URL。以下是对我有效的方法:
var getDomainName=函数(域){
var parts=domain.split('.').reverse();
var cnt=零件长度;
如果(cnt>=3){
//查看第二级域是否为普通SLD。
如果(部分[1]。匹配(/^(com | edu | gov | net | mil | org | nom | co | name | info | biz)$/i)){
退货零件[2]+'.+零件[1]+'.+零件[0];
}
}
返回零件[1]+'.+零件[0];
};
var isexternalur=函数(url){
var curLocationUrl=getDomainName(location.href.replace(“http://”,“”)。replace(“https://”,“”)。replace(“//”,“”)。split(“/”)[0]。toLowerCase());
var destinationUrl=getDomainName(url.replace(“http:/”,“”)。replace(“https:/”,“”)。replace(“/”,“”)。split(“/”)[0]。toLowerCase());
返回!(CurlLocationUrl===destinationUrl)
};
$(document).delegate('a','click',function(){
var aHrefTarget=$(this.attr('target');
如果(aHrefTarget的类型==='undefined')
返回;
如果(aHrefTarget!='\u blank')
return;//不是外部链接
var aHrefUrl=$(this.attr('href');
如果(aHrefUrl.substr(0,2)!='/'&&(aHrefUrl.substr(0,1)='/'| | aHrefUrl.substr(0,1)='.#'))
return;//这是相对链接或锚链接
if(isExternalUrl(AHREURL))
警报(“单击的外部链接”);
});代码>
内部URL:
外部URL:
不应该
function is_external( url ) {
return url.match( /[a-zA-Z0-9]*:\/\/[^\s]*/g ) != null;
}
玩这个把戏?不适用于绝对(内部)URL。主要问题是如何解析URL并获取其主机名。
可通过以下方式完成:
var _getHostname = function(url) {
var parser = document.createElement('a');
parser.href = url;
return parser.hostname;
}
var isExternal = (_getHostname(window.location.href) !== _getHostname('http://john.doe'));
或者您可以使用模块
出于我的目的,我只是对shshaw的答案做了一点修改,以验证链接是否为空或仅仅是一个字符(假设为“#”),哪个原始的答案方法返回假阳性。这是为了向用户表明,他们将通过添加一些FA图标离开我的页面
// same thing here, no edit
function checkDomain(url) {
if ( url.indexOf('//') === 0 ) { url = location.protocol + url; }
return url.toLowerCase().replace(/([a-z])?:\/\//,'$1').split('/')[0];
};
function isExternal(url) {
// verify if link is empty or just 1 char + original answer
return (url.length > 1 && url.indexOf(':') > -1 || url.indexOf('//') > -1 ) && checkDomain(location.href) !== checkDomain(url);
};
// add some icon to external links (function is called in an init method)
function addExternalLinkIcon(){
$("a[href]").each(function(i,ob){
// we check it
if(isExternal($(ob).attr("href"))){
// then add some beauty if it's external
// (we assume Font Awesome CSS and font is loaded for my example, of course :-P)
$(ob).append(" <i class='fa fa-external-link'></i> ");
}
});
}
//这里也是一样,没有编辑
函数检查域(url){
如果(url.indexOf('/')==0){url=location.protocol+url;}
返回url.toLowerCase().replace(/([a-z])?:\/\/,“$1”).split(“/”)[0];
};
函数isExternal(url){
//验证链接是否为空或仅为1个字符+原始答案
return(url.length>1&&url.indexOf(':')>-1 | url.indexOf('/')>-1)&&checkDomain(location.href)!==checkDomain(url);
};
//向外部链接添加一些图标(函数在init方法中调用)
函数adderExternalinkicon(){
$(“a[href]”)。每个(函数(i,ob){
//我们检查一下
如果(isExternal($(ob.attr(“href”)){
//如果是外部的,那就添加一些美
//(对于我的示例,我们假设加载了字体可怕的CSS和字体,当然:-P)
$(ob)。追加(“”);
}
});
}
您只需使用npm软件包即可
装置
npm install --save is-internal-link
用法
我通常也会这样反应
import React from 'react'
import { Link as ReactRouterLink} from 'react-router-dom'
import { isInternalLink } from 'is-internal-link'
const Link = ({ children, to, activeClassName, ...other }) => {
if (isInternalLink(to)) {
return (
<ReactRouterLink to={to} activeClassName={activeClassName} {...other}>
{children}
</ReactRouterLink>
)
}
return (
<a href={to} target="_blank" {...other}>
{children}
</a>
)
}
export default Link
从“React”导入React
从“react router dom”导入{Link as ReactRouterLink}
从“是内部链接”导入{isInternalLink}
常量链接=({children,to,activeClassName,…other})=>{
如果(isInternalLink(to)){
返回(
{儿童}
)
}
返回(
)
}
导出默认链接
<免责声明:我是这个LIB 的作者,你会考虑什么?不同的方案/主机/端口?快速、简单、准确:选择2?这可能是解决方案:@msec:你到底在用这些20k锚做什么?@roXon:正则表达式实际上是。谢谢gumbo!这在moz、webkit(safari和chrome)中起着火箭般的作用,但在InternetExplorer中却不起作用(全是假的)——为什么
import { isInternalLink } from "is-internal-link"
isInternalLink('https://www.google.com') // false
isInternalLink('/page1') // true
import React from 'react'
import { Link as ReactRouterLink} from 'react-router-dom'
import { isInternalLink } from 'is-internal-link'
const Link = ({ children, to, activeClassName, ...other }) => {
if (isInternalLink(to)) {
return (
<ReactRouterLink to={to} activeClassName={activeClassName} {...other}>
{children}
</ReactRouterLink>
)
}
return (
<a href={to} target="_blank" {...other}>
{children}
</a>
)
}
export default Link