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

IT技术 javascript jquery location href
2021-03-05 12:23:05

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

  1. 我无法对本地域进行硬编码。
  2. 我无法测试“http”。我可以很容易地使用 http 绝对链接链接到我自己的网站。
  3. 我想使用 jQuery/javascript,而不是 css。

我怀疑答案在 location.href 中的某个地方,但解决方案回避了我。

谢谢!

6个回答

我知道这篇文章很旧,但它仍然显示在结果的顶部,所以我想提供另一种方法。我看到了对锚元素的所有正则表达式检查,但为什么不直接使用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
    }
}
这是对我来说唯一有意义的答案——其他答案都过度设计了。是否有任何反对这种方法的论据?
2021-04-17 12:23:05
上面的 jQuery 在 Safari 中为我工作,并处理其他人处理的所有问题——本地锚点、相对 URL、跨协议 URL 等。注意:example.comexample.com将被标记为内部;这对你来说可能很重要。
2021-04-19 12:23:05
我在这里跟进有点晚了,但我会向@Andrew 争辩说,“www”是一个标识符,表示不同的匹配。尽管域可能相同,但 WWW 的主机会有所不同,我认为这是一个有效条件。如果它们都 != '',也可以使用“.port”比较来检查端口。
2021-04-19 12:23:05
这是最好的答案。这利用a.host了普通 JavaScript 开发人员(包括我在阅读本文之前)可能不知道属性。
2021-04-26 12:23:05
当指定端口号时,这将失败,如果“www”被遗漏
2021-05-03 12:23:05
var comp = new RegExp(location.host);

$('a').each(function(){
   if(comp.test($(this).attr('href'))){
       // a link that contains the current host           
       $(this).addClass('local');
   }
   else{
       // a link that does not contain the current host
       $(this).addClass('external');
   }
});

注意:这只是一个快速而肮脏的例子。它也会将所有 href="#anchor" 链接匹配为外部链接。可以通过进行一些额外的 RegExp 检查来改进它。


更新 2016-11-17

这个问题仍然有很多流量,很多人告诉我这个被接受的解决方案将多次失败。正如我所说,这是一个非常快速和肮脏的答案,展示了如何解决这个问题的主要方法。更复杂的解决方案是使用可在<a>(锚)元素上访问的属性像@Daved已经在这个回答中指出,关键是要比较hostname与当前window.location.hostname我更愿意比较这些hostname属性,因为如果它与 80 不同,它们从不包括port包含在host属性中的 。

所以我们开始:

$( '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' );
});
jsfiddle.net/zuSeh经验证,此方法不适用于相对网址。
2021-04-24 12:23:05
如果您使用 href 属性而不是 href 属性,它也适用于相对。
2021-04-29 12:23:05
我很确定这不适用于相对网址。attr应该返回属性,而不是属性(可能会解析属性,而不是属性)。
2021-05-09 12:23:05
我已经看到人们仍在查看这个问题和解决方案,所以我想链接到我在下面提出的解决方案,该解决方案应该处理所有检查而没有 RegEx 或相关问题:stackoverflow.com/a/18660968/2754848
2021-05-10 12:23:05
更新了答案。
2021-05-14 12:23:05

和无 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 都会被自动视为本地

如果您使用协议不可知的 url,这将不起作用,即: href="//somedomain.com/some-path"
2021-04-16 12:23:05
这个答案更准确。亲属 URL 也很重要。
2021-04-23 12:23:05
你为什么用一个while循环来做这个?在我看来,通过 $(document).on('click', 'a', function({}); 使用事件委托更有意义;并测试被点击的特定链接(在被点击时) ). 这样,您就不会不必要地遍历页面上的所有链接,并且它允许在初始 DOM 准备好后通过 ajax 添加到页面中的任何元素......实际上有时使用 jQuery 是有意义的(除了成为“粉丝”)。
2021-04-29 12:23:05
如果我没记错的话,“($|/”实际上应该是带有右大括号的“($|/)”
2021-05-09 12:23:05
这与解决方案很接近,但您还应该检查 href 属性是否以location.protocol+'//'+location.host. 检查这个小提琴:jsfiddle.net/framp/Ag3BT/1
2021-05-09 12:23:05
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');

用法:

external.test('some url'); // => true or false
+1 为正则表达式,虽然它没有完全解决问题
2021-04-24 12:23:05

这是一个仅用于外部链接的 jQuery 选择器:

$('a[href^="(http:|https:)?//"])') 

仅用于内部链接(不包括同一页面内的哈希链接)的 jQuery 选择器需要更复杂一些:

$('a:not([href^="(http:|https:)?//"],[href^="#"],[href^="mailto:"])')

额外的过滤器可以放置在:not()条件中,并根据需要用额外的逗号分隔。

http://jsfiddle.net/mblase75/Pavg2/


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

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

http://jsfiddle.net/mblase75/7z6EV/

仅供参考,您的外部选择器出现错误: Uncaught Error: Syntax error, unrecognized expression: a[href^="(http:|https:)?//"])
2021-04-22 12:23:05
+1:好的,有一种方法可以再次为您投票给您这个答案:)
2021-05-01 12:23:05
第一个不起作用,因为“//code.jquery.com/jquery.min.js”是一个完全合法的 URL,但不是内部的。协议和冒号不是必需的,因为浏览器将使用当前站点使用的任何内容(半协议相对 URL)。
2021-05-02 12:23:05