使用 jQuery/javascript 测试链接是否为外部链接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2910946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Test if links are external with jQuery / javascript?
提问by Matrym
How do I test to see if links are external or internal? Please note:
如何测试链接是外部链接还是内部链接?请注意:
- I cannot hard code the local domain.
- I cannot test for "http". I could just as easily be linking to my own site with an http absolute link.
- I want to use jQuery / javascript, not css.
- 我无法对本地域进行硬编码。
- 我无法测试“http”。我可以很容易地使用 http 绝对链接链接到我自己的网站。
- 我想使用 jQuery/javascript,而不是 css。
I suspect the answer lies somewhere in location.href, but the solution evades me.
我怀疑答案在 location.href 中的某个地方,但解决方案回避了我。
Thanks!
谢谢!
采纳答案by jAndy
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');
}
});
Note: this is just a quick & dirty example. It would match all href="#anchor" links as external too. It might be improved by doing some extra RegExp checking.
注意:这只是一个快速而肮脏的例子。它也会将所有 href="#anchor" 链接匹配为外部链接。可以通过进行一些额外的 RegExp 检查来改进它。
Update 2016-11-17
更新 2016-11-17
This question still got a lot of traffic and I was told by a ton of people that this accepted solution will fail on several occasions. As I stated, this was a very quick and dirty answer to show the principal way how to solve this problem. A more sophisticated solution is to use the properties which are accessible on a <a>(anchor) element. Like @Daved already pointed out in this answer, the key is to compare the hostnamewith the current window.location.hostname. I would prefer to compare the hostnameproperties, because they never include the portwhich is included to the hostproperty if it differs from 80.
这个问题仍然有很多流量,很多人告诉我这个被接受的解决方案将多次失败。正如我所说,这是一个非常快速和肮脏的答案,展示了如何解决这个问题的主要方法。更复杂的解决方案是使用可在<a>(锚)元素上访问的属性。像@Daved已经在这个回答中指出,关键是要比较hostname与当前window.location.hostname。我更愿意比较这些hostname属性,因为如果它不同于 80 ,它们从不包括port包含在host属性中的 。
So here we go:
所以我们开始:
$( 'a' ).each(function() {
if( location.hostname === this.hostname || !this.hostname.length ) {
$(this).addClass('local');
} else {
$(this).addClass('external');
}
});
State of the art:
最先进的:
Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
});
回答by Daved
I know this post is old but it still shows at the top of results so I wanted to offer another approach. I see all the regex checks on an anchor element, but why not just use window.location.hostand check against the element's hostproperty?
我知道这篇文章很旧,但它仍然显示在结果的顶部,所以我想提供另一种方法。我看到了对锚元素的所有正则表达式检查,但为什么不直接使用window.location.host和检查元素的host属性呢?
function link_is_external(link_element) {
return (link_element.host !== window.location.host);
}
With jQuery:
使用 jQuery:
$('a').each(function() {
if (link_is_external(this)) {
// External
}
});
and with plain javascript:
并使用普通的javascript:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
if (link_is_external(links[i])) {
// External
}
}
回答by Sean Kinsey
And the no-jQuery way
和无 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"));
}
All hrefs not beginning with http(http://, https://) are automatically treated as local
所有不以http(http://, https://)开头的 href 都会被自动视为本地
回答by James
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
Usage:
用法:
external.test('some url'); // => true or false
回答by Blazemonger
Here's a jQuery selector for only external links:
这是一个仅用于外部链接的 jQuery 选择器:
$('a[href^="(http:|https:)?//"])')
A jQuery selector only for internal links (not including hash links within the same page) needs to be a bit more complicated:
仅用于内部链接(不包括同一页面内的哈希链接)的 jQuery 选择器需要更复杂一些:
$('a:not([href^="(http:|https:)?//"],[href^="#"],[href^="mailto:"])')
Additional filters can be placed inside the :not()condition and separated by additional commas as needed.
额外的过滤器可以放置在:not()条件中,并根据需要用额外的逗号分隔。
http://jsfiddle.net/mblase75/Pavg2/
http://jsfiddle.net/mblase75/Pavg2/
Alternatively, we can filter internal links using the vanilla JavaScript hrefproperty, which is always an absolute URL:
或者,我们可以使用 vanilla JavaScripthref属性过滤内部链接,该属性始终是绝对 URL:
$('a').filter( function(i,el) {
return el.href.indexOf(location.protocol+'//'+location.hostname)===0;
})
回答by Freelance webdesigner NL
You forgot one, what if you use a relative path.
你忘记了,如果你使用相对路径怎么办。
forexample: /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');
}
});
There are also the issue of file downloads .zip (local en external) which could use the classes "local download" or "external download". But didn't found a solution for it yet.
还有文件下载 .zip (local en external) 的问题,它可以使用“本地下载”或“外部下载”类。但是还没有找到解决办法。
回答by mrded
You can use is-url-externalmodule.
您可以使用is-url-external模块。
var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false
回答by King Rayhan
/**
* All DOM url
* [links description]
* @type {[type]}
*/
var links = document.querySelectorAll('a');
/**
* Home Page Url
* [HomeUrl description]
* @type {[type]}
*/
var HomeUrl = 'https://stackoverflow.com/'; // Current Page url by-> window.location.href
links.forEach(function(link) {
link.addEventListener('click', function(e) {
e.preventDefault();
// Make lowercase of urls
var url = link.href.toLowerCase();
var isExternalLink = !url.includes(HomeUrl);
// Check if external or internal
if (isExternalLink) {
if (confirm('it\'s an external link. Are you sure to go?')) {
window.location = link.href;
}
} else {
window.location = link.href;
}
})
})
<a href="https://stackoverflow.com/users/3705299/king-rayhan">Internal Link</a>
<a href="https://wordpress.stackexchange.com/">External Link</a>
回答by fuuchi
This should work for any kind of link on every browser except IE.
这应该适用于除 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}
回答by Jacob Hixon
This doesn't exactly meet the "cannot hardcode my domain" prerequisite of the question, but I found this post searching for a similar solution, and in my case I couldhard code my url. My concern was alerting users that they are leaving the site, but not if they are staying on site,including subdomains(example: blog.mysite.com, which would fail in most of these other answers). So here is my solution, which takes some bits from the top voted answers above:
这并不完全符合问题的“无法对我的域进行硬编码”的先决条件,但我发现这篇文章正在寻找类似的解决方案,在我的情况下,我可以对我的网址进行硬编码。我担心的是提醒用户他们将离开网站,但如果他们留在网站上,则不会提醒用户,包括子域(例如: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();
}
}
});

