Проверить, являются ли ссылки внешними с помощью jQuery / javascript? - PullRequest
59 голосов
/ 26 мая 2010

Как мне проверить, являются ли ссылки внешними или внутренними? Пожалуйста, обратите внимание:

  1. Я не могу жестко кодировать локальный домен.
  2. Я не могу проверить «http». Я мог бы так же легко ссылаться на свой собственный сайт с абсолютной ссылкой http.
  3. Я хочу использовать jQuery / javascript, а не css.

Я подозреваю, что ответ лежит где-то в location.href, но решение уклоняется от меня.

Спасибо!

Ответы [ 12 ]

56 голосов
/ 06 сентября 2013

Я знаю, что этот пост старый, но он все еще отображается в верхней части результатов, поэтому я хотел предложить другой подход. Я вижу все проверки регулярных выражений для элемента привязки, но почему бы просто не использовать 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
    }
}
43 голосов
/ 26 мая 2010
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, поскольку они никогда не включают port, который включен в свойство host, если оно отличается от 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' );
});
37 голосов
/ 26 мая 2010

И не-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"));
}

Все hrefs не начинающиеся с http (http://, https://) автоматически считаются локальными

7 голосов
/ 06 июня 2014

Вот селектор 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/

7 голосов
/ 26 мая 2010
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');

Использование:

external.test('some url'); // => true or false
6 голосов
/ 06 ноября 2012

Вы забыли один, что если вы используете относительный путь.

пример: / тест

        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), в которой могут использоваться классы «локальная загрузка» или «внешняя загрузка». Но пока не нашел решения.

2 голосов
/ 19 декабря 2016

Вы можете использовать is-url-external модуль.

var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false 
1 голос
/ 01 октября 2018

Это должно работать для любых ссылок в любом браузере, кроме 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}
1 голос
/ 17 марта 2018

/**
     * 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>
0 голосов
/ 04 октября 2017

Я использую эту функцию для 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

...