使用jQuery/javascript测试链接是否为外部链接?

使用jQuery/javascript测试链接是否为外部链接?,javascript,jquery,location,href,Javascript,Jquery,Location,Href,如何测试链接是外部链接还是内部链接?请注意: 我无法硬编码本地域 我无法测试“http”。我可以用http绝对链接轻松地链接到我自己的站点 我想使用jQuery/javascript,而不是css 我怀疑答案在location.href的某个地方,但我没有找到答案 谢谢 是的,我相信您可以使用location.href检索当前域名。另一种可能是创建一个link元素,将src设置为/然后检索规范URL(如果使用,这将检索基本URL,而不一定是域名) 另请参见本帖: 注意:这只是一个简单的例子。它将

如何测试链接是外部链接还是内部链接?请注意:

  • 我无法硬编码本地域
  • 我无法测试“http”。我可以用http绝对链接轻松地链接到我自己的站点
  • 我想使用jQuery/javascript,而不是css
  • 我怀疑答案在location.href的某个地方,但我没有找到答案


    谢谢

    是的,我相信您可以使用location.href检索当前域名。另一种可能是创建一个link元素,将src设置为/然后检索规范URL(如果使用,这将检索基本URL,而不一定是域名)

    另请参见本帖:

    注意:这只是一个简单的例子。它将匹配所有href=“#锚定”链接 也像外部的。可以通过执行一些额外的RegExp检查来改进它


    更新2016-11-17

    这个问题仍然有很多流量,很多人告诉我,这个被接受的解决方案在很多情况下都会失败。正如我所说,这是一个非常快速和肮脏的答案,以显示如何解决这个问题的主要途径。更复杂的解决方案是使用
    (锚定)元素上可访问的属性。正如@Daved在这个答案中已经指出的,关键是将
    主机名
    与当前的
    window.location.hostname
    进行比较。我更愿意比较
    主机名
    属性,因为它们从不包括
    端口
    ,如果该端口与80不同,则包含在
    主机
    属性中

    现在我们开始:

    $( 'a' ).each(function() {
      if( location.hostname === this.hostname || !this.hostname.length ) {
          $(this).addClass('local');
      } else {
          $(this).addClass('external');
      }
    });
    
    最新技术:

    Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
        a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
    });
    
    以及无jQuery方式

    var nodes = document.getElementsByTagName("a"), i = nodes.length;
    var regExp = new RegExp("//" + location.host + "($|/)");
    while(i--){
        var href = nodes[i].href;
        var isLocal = (href.substring(0,4) === "http") ? regExp.test(href) : true;
        alert(href + " is " + (isLocal ? "local" : "not local"));
    }
    
    所有不以
    http
    (http://,https://)开头的HREF将自动视为本地文件

    var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
    
    用法:

    external.test('some url'); // => true or false
    

    你忘了一个,如果你用相对路径呢

    例如:/test

            hostname = new RegExp(location.host);
                // Act on each link
                $('a').each(function(){
    
                // Store current link's url
                var url = $(this).attr("href");
    
                // Test if current host (domain) is in it
                if(hostname.test(url)){
                   // If it's local...
                   $(this).addClass('local');
                }
                else if(url.slice(0, 1) == "/"){
                    $(this).addClass('local'); 
                }
                else if(url.slice(0, 1) == "#"){
                    // It's an anchor link
                    $(this).addClass('anchor'); 
                }
                else {
                   // a link that does not contain the current host
                   $(this).addClass('external');                        
                }
            });
    

    还有文件downloads.zip(local en external)的问题,它可以使用“local download”或“external download”类。但是还没有找到解决方法。

    我知道这篇文章很老了,但它仍然显示在结果的顶部,所以我想提供另一种方法。我看到锚元素上的所有正则表达式检查,但为什么不使用
    window.location.host
    并检查元素的
    host
    属性呢

    function link_is_external(link_element) {
        return (link_element.host !== window.location.host);
    }
    
    使用jQuery:

    $('a').each(function() {
        if (link_is_external(this)) {
            // External
        }
    });
    
    使用纯javascript:

    var links = document.getElementsByTagName('a');
    for (var i = 0; i < links.length; i++) {
        if (link_is_external(links[i])) {
            // External
        }
    }
    
    var links=document.getElementsByTagName('a');
    对于(变量i=0;i
    这里有一个只用于外部链接的jQuery选择器:

    $('a[href^="(http:|https:)?//"])') 
    
    仅用于内部链接(不包括同一页面中的哈希链接)的jQuery选择器需要稍微复杂一些:

    $('a:not([href^="(http:|https:)?//"],[href^="#"],[href^="mailto:"])')
    
    可以在
    :not()
    条件中放置其他筛选器,并根据需要用其他逗号分隔


    或者,我们可以使用vanilla JavaScript
    href
    属性过滤内部链接,该属性始终是绝对URL:

    $('a').filter( function(i,el) {
        return el.href.indexOf(location.protocol+'//'+location.hostname)===0;
    })
    

    对于那些感兴趣的人,我做了一个三元版本的if块,检查元素有哪些类以及附加了哪些类

    $(document).ready(function () {
        $("a").click(function (e) {
    
            var hostname = new RegExp(location.host);
            var url = $(this).attr("href");
    
            hostname.test(url) ?
            $(this).addClass('local') :
            url.slice(0, 1) == "/" && url.slice(-1) == "/" ?
            $(this).addClass('localpage') :
            url.slice(0, 1) == "#" ?
            $(this).addClass('anchor') :
            $(this).addClass('external');
    
            var classes = $(this).attr("class");
    
            console.log("Link classes: " + classes);
    
            $(this).hasClass("external") ? googleAnalytics(url) :
            $(this).hasClass("anchor") ? console.log("Handle anchor") : console.log("Handle local");
    
        });
    });
    
    谷歌分析部分可以忽略,但现在你知道了链接的类型,你可能想在这里对url做些什么。只需在三元块中添加代码。 如果您只想检查1种类型的链接,那么用If语句替换ternaries

    编辑以添加我遇到的问题。我的一些HREF是这样的“/课程/”。我检查了一个localpage,检查href的开头和结尾是否有斜杠。尽管在开始时只检查“/”可能就足够了。

    您可以使用模块


    我将此函数用于jQuery:

    $.fn.isExternal = function() {
      var host = window.location.host;
      var link = $('<a>', {
        href: this.attr('href')
      })[0].hostname;
      return (link !== host);
    };
    
    $.fn.isExternal=函数(){
    var host=window.location.host;
    var link=$('

    /**
    *所有DOM url
    *[链接说明]
    *@type{[type]}
    */
    var links=document.querySelectorAll('a');
    /**
    *主页Url
    *[主页URL说明]
    *@type{[type]}
    */
    var HomeUrl=https://stackoverflow.com/“;//当前页面url by->window.location.href
    links.forEach(函数(link){
    link.addEventListener('click',函数(e){
    e、 预防默认值();
    //将URL设置为小写
    var url=link.href.toLowerCase();
    var isexternalink=!url.includes(HomeUrl);
    //检查是外部的还是内部的
    如果(Isexternalink){
    如果(确认('这是一个外部链接,你确定要去吗?')){
    window.location=link.href;
    }
    }否则{
    window.location=link.href;
    }
    })
    })

    这应该适用于除IE之外的所有浏览器上的任何类型的链接

    // check if link points outside of app - not working in IE
                    try {
                        const href = $linkElement.attr('href'),
                            link = new URL(href, window.location);
    
                        if (window.location.host === link.host) {
                            // same app
                        } else {
                            // points outside
                        }
                    } catch (e) { // in case IE happens}
    

    这并不完全符合问题的“无法硬编码我的域”前提条件,但我发现这篇文章在搜索类似的解决方案,在我的情况下,我可以硬编码我的url。我担心的是提醒用户他们将离开网站,但如果他们留在网站,包括子域(例如:blog.mysite.com,它在大多数其他答案中都会失败)。下面是我的解决方案,它从上面投票数最高的答案中提取了一些信息:

    Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
      a.classList.add( a.hostname.includes("mywebsite.com") ? 'local' : 'external' );
    });
    
    $("a").on("click", function(event) {
      if ($(this).hasClass('local')) {
        return;
      } else if ($(this).hasClass('external')) {
        if (!confirm("You are about leave the <My Website> website.")) {
          event.preventDefault();
        }
      }
    });
    
    Array.from(document.querySelectorAll('a')).forEach(a=>{
    a、 add(a.hostname.includes(“mywebsite.com”)?“local”:“external”);
    });
    $(“a”)。在(“单击”)上,函数(事件){
    if($(this).hasClass('local')){
    返回;
    }else if($(this).hasClass('external')){
    如果(!确认(“您即将离开网站”){
    event.preventDefault();
    }
    }
    });
    
    是否要在单击链接时或在页面加载时进行检查?您的答案无效。所有检查都应在
    元素上进行。href
    // check if link points outside of app - not working in IE
                    try {
                        const href = $linkElement.attr('href'),
                            link = new URL(href, window.location);
    
                        if (window.location.host === link.host) {
                            // same app
                        } else {
                            // points outside
                        }
                    } catch (e) { // in case IE happens}
    
    Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
      a.classList.add( a.hostname.includes("mywebsite.com") ? 'local' : 'external' );
    });
    
    $("a").on("click", function(event) {
      if ($(this).hasClass('local')) {
        return;
      } else if ($(this).hasClass('external')) {
        if (!confirm("You are about leave the <My Website> website.")) {
          event.preventDefault();
        }
      }
    });