簡體   English   中英

測試鏈接是否為外部鏈接 jQuery / javascript?

[英]Test if links are external with jQuery / javascript?

如何測試鏈接是外部鏈接還是內部鏈接? 請注意:

  1. 我無法對本地域進行硬編碼。
  2. 我無法測試“http”。 我可以很容易地使用 http 絕對鏈接鏈接到我自己的網站。
  3. 我想使用 jQuery / javascript,而不是 css。

我懷疑答案就在 location.href 的某處,但解決方案讓我望而卻步。

謝謝!

我知道這篇文章很舊,但它仍然顯示在結果的頂部,所以我想提供另一種方法。 我看到了對錨元素的所有正則表達式檢查,但為什么不只使用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 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屬性,因為它們從不包括包含在host屬性中的port ,如果它不同於 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

這是一個僅用於外部鏈接的 jQuery 選擇器:

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

僅用於內部鏈接(不包括同一頁面內的哈希鏈接)的 jQuery 選擇器需要更復雜一些:

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

額外的過濾器可以放置在:not()條件中,並根據需要用額外的逗號分隔。

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


或者,我們可以使用 vanilla JavaScript href屬性過濾內部鏈接,該屬性始終是絕對 URL:

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

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

你忘記了,如果你使用相對路徑怎么辦。

例如:/測試

        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');                        
            }
        });

還有文件下載 .zip (local en external) 的問題,它可以使用“本地下載”或“外部下載”類。 但是還沒有找到解決辦法。

您可以使用is-url-external模塊。

var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false 

使用 jQuery

 jQuery('a').each(function() { if (this.host !== window.location.host) { console.log(jQuery(this).attr('href')); } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

const isExternalLink = (url) => {
    const tmp = document.createElement('a');
    tmp.href = url;
    return tmp.host !== window.location.host;
};

// output: true
console.log(isExternalLink('https://foobar.com'));
console.log(isExternalLink('//foobar.com'));

// output: false
console.log(isExternalLink('https://www.stackoverflow.com'));
console.log(isExternalLink('//www.stackoverflow.com'));
console.log(isExternalLink('/foobar'));
console.log(isExternalLink('#foobar'));

使用這種方法的好處是:

  • 它會自動解析相對路徑和片段的hostname
  • 它適用於protocol-relative URL

為了證明這一點,讓我們看一下以下示例:

const lnk = document.createElement('a');
lnk.href = '/foobar';

console.log(lnk.host); // output: 'www.stackoverflow.com'
const lnk = document.createElement('a');
lnk.href = '#foobar';

console.log(lnk.host); // output: 'www.stackoverflow.com'
const lnk = document.createElement('a');
lnk.href = '//www.stackoverflow.com';

console.log(lnk.host); // output: 'www.stackoverflow.com'

 /** * 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>

這應該適用於除 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}

是的,我相信您可以通過location.href 檢索當前域名。 另一種可能性是創建一個鏈接元素,將 src 設置為 /,然后檢索規范 URL(如果您使用一個,這將檢索基本 URL,而不一定是域名)。

另請參閱此帖子: 從鏈接的 href 屬性獲取完整的 URI

對於那些感興趣的人,我做了一個 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");

    });
});

可以忽略 google 分析位,但是現在您可能希望對 url 執行某些操作,因為您知道它是什么類型的鏈接。 只需在三元塊內添加代碼。 如果您只想檢查 1 種類型的鏈接,請用 if 語句替換三元組。

編輯以添加我遇到的問題。 我的一些 href 是“/Courses/”,就像這樣。 我檢查了一個localpage,它檢查href的開頭和結尾是否有斜線。 盡管在開始時檢查“/”可能就足夠了。

我將此函數用於 jQuery:

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

用法是: $('a').isExternal();

示例: https : //codepen.io/allurewebsolutions/pen/ygJPgV

這並不完全符合問題的“無法對我的域進行硬編碼”的先決條件,但我發現這篇文章正在尋找類似的解決方案,在我的情況下,我可以對我的網址進行硬編碼。 我擔心的是提醒用戶他們將離開網站,但如果他們留在網站上,包括子域(例如: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();
    }
  }
});

這對我有用:

function strip_scheme( url ) {
    return url.replace(/^(?:(?:f|ht)tp(?:s)?\:)?\/\/(www\.)?/g, '');
  }

  function is_link_external( elem ) {
    let domain = strip_scheme( elem.attr('href') );
    let host = strip_scheme( window.location.host );

    return ! domain.indexOf(host) == 0;
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM