Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检测外部URL的最快方法_Url_Javascript_Location_Href - Fatal编程技术网

检测外部URL的最快方法

检测外部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){

检测if
foo=”的最快方法是什么http://john.doe“
是外部的(与
window.location.href
相比)
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
vs
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) );
};
以下是一些使用更新功能的测试:

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