webentwicklung-frage-antwort-db.com.de

Testen Sie, ob Links extern mit jQuery/Javascript sind?

Wie teste ich, ob Links extern oder intern sind? Bitte beachten Sie:

  1. Ich kann die lokale Domäne nicht hart codieren.
  2. Ich kann nicht auf "http" testen. Ich könnte genauso einfach mit einem absoluten HTTP-Link auf meine eigene Website verlinken.
  3. Ich möchte jQuery/javascript verwenden, nicht css.

Ich vermute, die Antwort liegt irgendwo in location.href, aber die Lösung weicht mir aus.

Vielen Dank!

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

Hinweis: Dies ist nur ein schnelles und schmutziges Beispiel. Es würde alle externen href = "# anchor" -Links Es kann durch zusätzliche RegExp-Überprüfungen verbessert werden.


Update 2016-11-17

Diese Frage hatte immer noch viel Verkehr und mir wurde von einer Menge Menschen gesagt, dass diese akzeptierte Lösung mehrmals versagen wird. Wie ich schon sagte, war dies eine sehr schnelle und schmutzige Antwort, um den wichtigsten Weg aufzuzeigen, wie man dieses Problem lösen kann. Eine komplexere Lösung besteht darin, die Eigenschaften zu verwenden, die auf ein <a> (Anker) -Element verfügbar sind. Wie in dieser Antwort bereits auf @Daved hingewiesen wurde, besteht der Schlüssel darin, hostname mit dem aktuellen window.location.hostname zu vergleichen. Ich würde es vorziehen, die hostname-Eigenschaften zu vergleichen, da sie niemals das port enthalten, das in der Host-Eigenschaft enthalten ist, wenn es sich von 80 unterscheidet.

Auf geht's:

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

Der letzte Stand der Technik:

Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
    a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
});
40
jAndy

Ich weiß, dass dieser Beitrag alt ist, aber er zeigt immer noch die Spitze der Ergebnisse. Ich wollte einen anderen Ansatz anbieten. Ich sehe alle Regex-Prüfungen auf einem Ankerelement, aber warum verwenden Sie nicht einfach window.location.Host und prüfen mit der Host -Eigenschaft des Elements?

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

Mit jQuery:

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

und mit einfachem Javascript:

var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
    if (link_is_external(links[i])) {
        // External
    }
}
53
Daved

Und der No-JQuery-Weg

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

Alle Hrefs, die nicht mit http (http: //, https: //) beginnen, werden automatisch als lokal behandelt 

37
Sean Kinsey
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.Host + ')');

Verwendungszweck:

external.test('some url'); // => true or false
7
James

Hier ist ein jQuery-Selektor für nur externe Links:

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

Ein jQuery-Selektor nur für interne Links (ohne Hash-Links auf derselben Seite) muss etwas komplizierter sein:

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

Zusätzliche Filter können innerhalb der :not()-Bedingung platziert und bei Bedarf durch zusätzliche Kommas getrennt werden.

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


Alternativ können wir interne Links mit der Vanilla JavaScript-Eigenschaft href filtern, die immer eine absolute URL ist:

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

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

7
Blazemonger

Sie haben einen vergessen, wenn Sie einen relativen Pfad verwenden.

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

Es gibt auch die Ausgabe von Dateidownloads .Zip (local und external), die die Klassen "local download" oder "external download" verwenden können. Aber noch keine Lösung gefunden.

Dies sollte für alle Arten von Links in allen Browsern außer IE funktionieren.

// 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}
2
fuuchi

Sie können is-url-external module verwenden.

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

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

Ich verwende diese Funktion für jQuery:

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

Verwendung ist: $('a').isExternal();

Beispiel: https://codepen.io/allurewebsolutions/pen/ygJPgV

Für Interessierte habe ich eine ternäre Version des if-Blocks durchgeführt, um zu sehen, welche Klassen das Element hat und welche Klasse angehängt wird.

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

    });
});

Das Google Analytics-Bit kann ignoriert werden, aber hier möchten Sie wahrscheinlich etwas mit der URL tun, da Sie wissen, um welche Art von Link es sich handelt. Fügen Sie einfach Code in den ternären Block ein. Wenn Sie nur einen Link-Typ überprüfen möchten, ersetzen Sie stattdessen die Ternare durch eine if-Anweisung.

Bearbeitet, um ein Problem hinzuzufügen, auf das ich gestoßen bin. Einige meiner Hrefs waren "/ Courses /" so. Ich habe nach einer lokalen Seite gesucht, die prüft, ob am Anfang und am Ende der Href ein Schrägstrich steht. Zwar reicht es schon aus, nur nach einem '/' zu suchen.

0

Ja, ich glaube, Sie können den aktuellen Domainnamen mit location.href abrufen. Eine andere Möglichkeit besteht darin, ein Link-Element zu erstellen, den Wert für src auf/zu setzen und dann die kanonische URL abzurufen (dies ruft die Basis-URL ab, wenn Sie eine verwenden, und nicht unbedingt den Domänennamen).

Siehe auch diesen Beitrag: Holen Sie sich den vollständigen URI von der href-Eigenschaft eines Links

0
Savageman