Test czy linki są zewnętrzne z jQuery / javascript?

Jak sprawdzić, czy linki są zewnętrzne czy wewnętrzne? Uwaga:

  1. nie mogę na twardo zakodować lokalnej domeny.
  2. nie mogę przetestować "http". Równie łatwo mógłbym połączyć się z własną witryną za pomocą bezwzględnego linku http.
  3. chcę używać jQuery / javascript, nie css.

Podejrzewam, że odpowiedź leży gdzieś w miejscu.href, ale rozwiązanie mi umyka.

Dzięki!

Author: Bhargav Rao, 2010-05-26

12 answers

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

Uwaga: to tylko szybki i brudny przykład. Pasuje do wszystkich linków href= "# anchor" jako zewnętrzny też. Można to poprawić, wykonując dodatkowe sprawdzanie wyrażeń regularnych.


Aktualizacja 2016-11-17

To pytanie wciąż ma duży ruch i powiedziano mi przez mnóstwo ludzi, że to przyjęte rozwiązanie nie będzie przy kilku okazjach. Jak stwierdziłem, była to bardzo szybka i brudna odpowiedź, aby pokazać główny sposób rozwiązania tego problemu. Bardziej wyrafinowany rozwiązaniem jest użycie właściwości dostępnych dla elementu <a> (anchor). Tak jak @Daved już wskazał w tej odpowiedzi, kluczem jest porównanie hostname z bieżącym window.location.hostname. Wolałbym porównać właściwości hostname, ponieważ nigdy nie zawierają port, która jest dołączona do właściwości host, jeśli różni się od 80.

No to zaczynamy:

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

Stan techniki:

Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
    a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
});
 40
Author: jAndy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-16 23:44:38

Wiem, że ten post jest stary, ale nadal pokazuje się na szczycie wyników, więc chciałem zaoferować inne podejście. Widzę wszystkie sprawdzania regex na elemencie kotwicy, ale dlaczego po prostu nie użyć window.location.host i sprawdzić właściwości host elementu?

function link_is_external(link_element) {
    return (link_element.host !== window.location.host);
}

Z jQuery:

$('a').each(function() {
    if (link_is_external(this)) {
        // External
    }
});

I ze zwykłym javascript:

var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
    if (link_is_external(links[i])) {
        // External
    }
}
 51
Author: Daved,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-29 20:48:11

I sposób no-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"));
}

Wszystkie href nie zaczynające się od http (http://, https://) są automatycznie traktowane jako lokalne

 37
Author: Sean Kinsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-27 03:22:40
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');

Użycie:

external.test('some url'); // => true or false
 7
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-26 08:28:14

Oto selektor jQuery tylko dla linków zewnętrznych:

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

Selektor jQuery tylko dla linków wewnętrznych (bez linków hashowych na tej samej stronie) musi być nieco bardziej skomplikowany:

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

Dodatkowe filtry mogą być umieszczone wewnątrz warunku :not() i oddzielone dodatkowymi przecinkami w razie potrzeby.

Http://jsfiddle.net/mblase75/Pavg2/


Alternatywnie możemy filtrować linki wewnętrzne za pomocą właściwości vanilla JavaScript href, która jest zawsze bezwzględnym adresem URL:

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

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

 7
Author: Blazemonger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-21 19:16:58

Zapomniałeś jednego, co jeśli użyjesz ścieżki względnej.

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

Istnieje również problem pobierania plików .zip (local en external), które mogą używać klas "local download" lub "external download". Ale nie znalazłem na to jeszcze rozwiązania.

 6
Author: Freelance webdesigner NL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-06 13:48:08

Możesz użyć is-url-external module.

var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false 
 2
Author: mrded,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 14:32:55

/**
     * 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>
 1
Author: King Rayhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-17 10:20:31

Tak, wierzę, że możesz pobrać aktualną nazwę domeny z lokalizacją.href. Inną możliwością jest utworzenie elementu łącza, ustawienie src na/, a następnie pobranie kanonicznego adresu URL (spowoduje to pobranie podstawowego adresu URL, jeśli go użyjesz, a niekoniecznie nazwy domeny).

Zobacz również ten post: Pobierz pełny URI z właściwości href linku

 0
Author: Savageman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:57

Dla zainteresowanych wykonałem trójdzielną wersję bloku if z sprawdzeniem, jakie klasy posiada element i jaka Klasa zostanie dołączona.

$(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");

    });
});

Bit google analytics można zignorować, ale to jest miejsce, w którym prawdopodobnie chciałbyś zrobić coś z adresem url, teraz, gdy wiesz, jakiego rodzaju jest to link. Wystarczy dodać kod wewnątrz bloku trójdzielnego. Jeśli chcesz sprawdzić tylko 1 typ łącza, zamiast tego zastąp ternary instrukcją if.

Edited to add in an issue I came w poprzek. Niektóre z moich hrefs były "/ kursy / " jak tak. Sprawdziłem stronę lokalną, która sprawdza, czy na początku i końcu href jest ukośnik. Chociaż samo sprawdzanie " / " na początku jest prawdopodobnie wystarczające.

 0
Author: George F Delaney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-23 13:50:57

Używam tej funkcji do jQuery:

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

Użycie to: $('a').isExternal();

Przykład: https://codepen.io/allurewebsolutions/pen/ygJPgV

 0
Author: Allure Web Solutions,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-03 22:22:01

To powinno działać dla każdego rodzaju łącza w każdej przeglądarce z wyjątkiem 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}
 0
Author: fuuchi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 12:52:33