web-dev-qa-db-de.com

Extrahieren Sie den Hostnamen aus der Zeichenfolge

Ich möchte nur die Wurzel einer URL und nicht die gesamte URL aus einer Textzeichenfolge abgleichen. Gegeben: 

http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random

Ich möchte, dass die letzten 2 Instanzen in der www.example.com- oder example.com-Domäne aufgelöst werden. 

Ich habe gehört, dass der Regex langsam ist und dies wäre mein zweiter Regex-Ausdruck auf der Seite.

Ich suche eine JS/jQuery-Version dieser Lösung.

188
Chamilyan

Ich empfehle die Verwendung des npm-Pakets psl (Public Suffix List) . Die "Public Suffix List" ist eine Liste aller gültigen Domain-Suffixe und -Regeln, nicht nur Country-Top-Level-Domains, sondern auch Unicode-Zeichen, die als Stammdomäne betrachtet werden würden (dh www. 食 狮kobe.jp usw.). Lesen Sie mehr darüber hier .

Versuchen:

npm install --save psl

Dann mit meiner Implementation "extractHostname":

let psl = require('psl');
let url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
psl.get(extractHostname(url)); // returns youtube.com

Ich kann kein npm-Paket verwenden, so dass im Folgenden nur extractHostname getestet wird.

function extractHostname(url) {
    var hostname;
    //find & remove protocol (http, ftp, etc.) and get hostname

    if (url.indexOf("//") > -1) {
        hostname = url.split('/')[2];
    }
    else {
        hostname = url.split('/')[0];
    }

    //find & remove port number
    hostname = hostname.split(':')[0];
    //find & remove "?"
    hostname = hostname.split('?')[0];

    return hostname;
}

//test the code
console.log("== Testing extractHostname: ==");
console.log(extractHostname("http://www.blog.classroom.me.uk/index.php"));
console.log(extractHostname("http://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("https://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("ftps://ftp.websitename.com/dir/file.txt"));
console.log(extractHostname("websitename.com:1234/dir/file.txt"));
console.log(extractHostname("ftps://websitename.com:1234/dir/file.txt"));
console.log(extractHostname("example.com?param=value"));
console.log(extractHostname("https://facebook.github.io/jest/"));
console.log(extractHostname("//youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("http://localhost:4200/watch?v=ClkQA2Lb_iE"));

Unabhängig davon, welches Protokoll oder sogar die Portnummer vorhanden ist, können Sie die Domäne extrahieren. Dies ist eine sehr vereinfachte Lösung ohne Regex, also denke ich, dass dies funktionieren wird.

* Danke @Timmerz, @renoirb, @rineez, @BigDong, @ ra00l, @ILikeBeansTacos, @CharlesRobertson für Ihre Vorschläge! @ ross-allen, vielen dank für die meldung des bugs!

235
lewdev

Ein ordentlicher Trick ohne reguläre Ausdrücke:

var tmp        = document.createElement ('a');
;   tmp.href   = "http://www.example.com/12xy45";

// tmp.hostname will now contain 'www.example.com'
// tmp.Host will now contain hostname and port 'www.example.com:80'

Wenn Sie das Obige in eine Funktion wie die folgende packen, haben Sie eine hervorragende Möglichkeit, den Domain-Teil aus einem URI herauszuholen.

function url_domain(data) {
  var    a      = document.createElement('a');
         a.href = data;
  return a.hostname;
}
276

Versuche dies:

var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];  // domain will be null if no match is found

Wenn Sie den Port von Ihrem Ergebnis ausschließen möchten, verwenden Sie stattdessen diesen Ausdruck:

/^https?\:\/\/([^\/:?#]+)(?:[\/:?#]|$)/i

Bearbeiten: Verwenden Sie ein negatives Lookahead, um das Abgleichen bestimmter Domains zu verhindern. (?!youtube.com)

/^https?\:\/\/(?!(?:www\.)?(?:youtube\.com|youtu\.be))([^\/:?#]+)(?:[\/:?#]|$)/i
105
gilly3

Die Zeichenfolge muss nicht analysiert werden. Übergeben Sie einfach Ihre URL als Argument an den URL-Konstruktor :

var url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
var hostname = (new URL(url)).hostname;

assert(hostname === 'www.youtube.com');
74
Pavlo

Das Analysieren einer URL kann schwierig sein, da Sie Portnummern und Sonderzeichen verwenden können. Daher empfehle ich, etwas wie parseUri zu verwenden, um dies für Sie zu tun. Ich bezweifle, dass Leistung ein Problem sein wird, wenn Sie nicht hunderte von URLs analysieren.

36
Andrew White

Ich habe versucht, die Given-Lösungen zu verwenden, die Auserwählte war ein Overkill für meine Zwecke und "Das Erstellen eines Elements" wird für mich durcheinander gebracht.

Es ist noch nicht bereit für Port in URL. Ich hoffe jemand findet es nützlich

function parseURL(url){
    parsed_url = {}

    if ( url == null || url.length == 0 )
        return parsed_url;

    protocol_i = url.indexOf('://');
    parsed_url.protocol = url.substr(0,protocol_i);

    remaining_url = url.substr(protocol_i + 3, url.length);
    domain_i = remaining_url.indexOf('/');
    domain_i = domain_i == -1 ? remaining_url.length - 1 : domain_i;
    parsed_url.domain = remaining_url.substr(0, domain_i);
    parsed_url.path = domain_i == -1 || domain_i + 1 == remaining_url.length ? null : remaining_url.substr(domain_i + 1, remaining_url.length);

    domain_parts = parsed_url.domain.split('.');
    switch ( domain_parts.length ){
        case 2:
          parsed_url.subdomain = null;
          parsed_url.Host = domain_parts[0];
          parsed_url.tld = domain_parts[1];
          break;
        case 3:
          parsed_url.subdomain = domain_parts[0];
          parsed_url.Host = domain_parts[1];
          parsed_url.tld = domain_parts[2];
          break;
        case 4:
          parsed_url.subdomain = domain_parts[0];
          parsed_url.Host = domain_parts[1];
          parsed_url.tld = domain_parts[2] + '.' + domain_parts[3];
          break;
    }

    parsed_url.parent_domain = parsed_url.Host + '.' + parsed_url.tld;

    return parsed_url;
}

Ausführen dieses:

parseURL('https://www.facebook.com/100003379429021_356001651189146');

Ergebnis:

Object {
    domain : "www.facebook.com",
    Host : "facebook",
    path : "100003379429021_356001651189146",
    protocol : "https",
    subdomain : "www",
    tld : "com"
}
14
BlackDivine

Wenn Sie auf dieser Seite landen und nach den besten URLs von REGEX suchen, probieren Sie diese aus:

^(?:https?:)?(?:\/\/)?([^\/\?]+)

https://regex101.com/r/pX5dL9/1

Es funktioniert für URLs ohne http: //, mit http, mit https, nur mit // und greift auch nicht den Pfad und den Abfragepfad.

Viel Glück

13
Luis Lopes

Dies ist keine vollständige Antwort, aber der folgende Code sollte Ihnen helfen:

function myFunction() {
    var str = "https://www.123rf.com/photo_10965738_lots-oop.html";
    matches = str.split('/');
    return matches[2];
}

Ich möchte, dass jemand Code schneller als meiner erstellt. Es hilft auch, mein Selbst zu verbessern.

4
solokiran

Alle URL-Eigenschaften, keine Abhängigkeiten, kein JQuery, leicht verständlich

Diese Lösung gibt Ihre Antwort und zusätzliche Eigenschaften. Keine JQuery oder andere Abhängigkeiten erforderlich, einfügen und loslegen. 

Verwendungszweck

getUrlParts("https://news.google.com/news/headlines/technology.html?ned=us&hl=en")

Ausgabe

{
  "Origin": "https://news.google.com",
  "domain": "news.google.com",
  "subdomain": "news",
  "domainroot": "google.com",
  "domainpath": "news.google.com/news/headlines",
  "tld": ".com",
  "path": "news/headlines/technology.html",
  "query": "ned=us&hl=en",
  "protocol": "https",
  "port": 443,
  "parts": [
    "news",
    "google",
    "com"
  ],
  "segments": [
    "news",
    "headlines",
    "technology.html"
  ],
  "params": [
    {
      "key": "ned",
      "val": "us"
    },
    {
      "key": "hl",
      "val": "en"
    }
  ]
}

Code
Der Code ist so gestaltet, dass er einfach zu verstehen ist und nicht superschnell. Es kann problemlos 100 Mal pro Sekunde aufgerufen werden. Daher eignet es sich hervorragend für Front-End-Server oder einige Servernutzungen, nicht jedoch für hohen Datendurchsatz.

function getUrlParts(fullyQualifiedUrl) {
    var url = {},
        tempProtocol
    var a = document.createElement('a')
    // if doesn't start with something like https:// it's not a url, but try to work around that
    if (fullyQualifiedUrl.indexOf('://') == -1) {
        tempProtocol = 'https://'
        a.href = tempProtocol + fullyQualifiedUrl
    } else
        a.href = fullyQualifiedUrl
    var parts = a.hostname.split('.')
    url.Origin = tempProtocol ? "" : a.Origin
    url.domain = a.hostname
    url.subdomain = parts[0]
    url.domainroot = ''
    url.domainpath = ''
    url.tld = '.' + parts[parts.length - 1]
    url.path = a.pathname.substring(1)
    url.query = a.search.substr(1)
    url.protocol = tempProtocol ? "" : a.protocol.substr(0, a.protocol.length - 1)
    url.port = tempProtocol ? "" : a.port ? a.port : a.protocol === 'http:' ? 80 : a.protocol === 'https:' ? 443 : a.port
    url.parts = parts
    url.segments = a.pathname === '/' ? [] : a.pathname.split('/').slice(1)
    url.params = url.query === '' ? [] : url.query.split('&')
    for (var j = 0; j < url.params.length; j++) {
        var param = url.params[j];
        var keyval = param.split('=')
        url.params[j] = {
            'key': keyval[0],
            'val': keyval[1]
        }
    }
    // domainroot
    if (parts.length > 2) {
        url.domainroot = parts[parts.length - 2] + '.' + parts[parts.length - 1];
        // check for country code top level domain
        if (parts[parts.length - 1].length == 2 && parts[parts.length - 1].length == 2)
            url.domainroot = parts[parts.length - 3] + '.' + url.domainroot;
    }
    // domainpath (domain+path without filenames) 
    if (url.segments.length > 0) {
        var lastSegment = url.segments[url.segments.length - 1]
        var endsWithFile = lastSegment.indexOf('.') != -1
        if (endsWithFile) {
            var fileSegment = url.path.indexOf(lastSegment)
            var pathNoFile = url.path.substr(0, fileSegment - 1)
            url.domainpath = url.domain
            if (pathNoFile)
                url.domainpath = url.domainpath + '/' + pathNoFile
        } else
            url.domainpath = url.domain + '/' + url.path
    } else
        url.domainpath = url.domain
    return url
}
3
whitneyland

oneline mit jquery

$('<a>').attr('href', document.location.href).prop('hostname');
3
VnDevil
function hostname(url) {
    var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i);
    if ( match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0 ) return match[2];
}

Der obige Code analysiert erfolgreich die Hostnamen für die folgenden Beispiel-URLs:

http://WWW.first.com/folder/page.html first.com

http://mail.google.com/folder/page.html mail.google.com

https://mail.google.com/folder/page.html mail.google.com

http://www2.somewhere.com/folder/page.html?q=1 somewhere.com

https://www.another.eu/folder/page.html?q=1 ein anderes.eu

Der ursprüngliche Kredit geht an: http://www.primaryobjects.com/CMS/Article145

2
jaggedsoft
String.prototype.trim = function(){return his.replace(/^\s+|\s+$/g,"");}
function getHost(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    var _Host,_arr;
    if(-1<url.indexOf("://")){
        _arr = url.split('://');
        if(-1<_arr[0].indexOf("/")||-1<_arr[0].indexOf(".")||-1<_arr[0].indexOf("\?")||-1<_arr[0].indexOf("\&")){
            _arr[0] = _arr[0].trim();
            if(0==_arr[0].indexOf("//")) _Host = _arr[0].split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
            else return "";
        }
        else{
            _arr[1] = _arr[1].trim();
            _Host = _arr[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
        }
    }
    else{
        if(0==url.indexOf("//")) _Host = url.split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
        else return "";
    }
    return _Host;
}
function getHostname(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    return getHost(url).split(':')[0];
}
function getDomain(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    return getHostname(url).replace(/([a-zA-Z0-9]+.)/,"");
}
2
QazyCat

War heute auf der Suche nach einer Lösung für dieses Problem. Keine der obigen Antworten schien zu befriedigen. Ich wollte eine Lösung, die ein Einzeiler sein könnte, keine bedingte Logik und nichts, was in eine Funktion eingeschlossen werden muss.

Hier ist, was ich erfunden habe, scheint wirklich gut zu funktionieren:

 hostname = "http://www.example.com:1234" 
 hostname.split ("//") .slice (-1) [0] .split (":") [0]. split ('.'). slice (-2) .join ('.') // gibt "example.com" 

Mag auf den ersten Blick kompliziert aussehen, aber es funktioniert ziemlich einfach; Der Schlüssel verwendet 'Slice (-n)' an einigen Stellen, an denen der gute Teil vom Ende des Split-Arrays gezogen werden muss (und [0], um von der Vorderseite des Split-Arrays zu gelangen). .

Jeder dieser Tests gibt "example.com" zurück:

 "http://example.com" .split ("//") .slice (-1) [0] .split (":") [0] .split ('.'). slice (- 2) .join ('.') 
 "Http://example.com:1234" .split ("//") .slice (-1) [0] .split (":") [0] .split ('.'). slice (-2) .join ('.') 
 "http://www.example.com:1234" .split ("//") .slice (-1) [0] .split (":") [0] .split ('.'). Slice (-2) .join ('.') 
 "Http://foo.www.example.com:1234 ".split (" // "). slice (-1) [0] .split (": ") [0] .split ('.'). slice (-2) .join ('.') 
2
zaphodb

Okay, ich weiß, das ist eine alte Frage, aber ich habe einen sehr effizienten URL-Parser erstellt und dachte, ich würde ihn teilen.

Wie Sie sehen, ist die Struktur der Funktion sehr seltsam, aber aus Effizienzgründen. Es werden keine Prototypfunktionen verwendet, der String wird nur einmal wiederholt und kein Zeichen wird mehr als nötig verarbeitet.

function getDomain(url) {
    var dom = "", v, step = 0;
    for(var i=0,l=url.length; i<l; i++) {
        v = url[i]; if(step == 0) {
            //First, skip 0 to 5 characters ending in ':' (ex: 'https://')
            if(i > 5) { i=-1; step=1; } else if(v == ':') { i+=2; step=1; }
        } else if(step == 1) {
            //Skip 0 or 4 characters 'www.'
            //(Note: Doesn't work with www.com, but that domain isn't claimed anyway.)
            if(v == 'w' && url[i+1] == 'w' && url[i+2] == 'w' && url[i+3] == '.') i+=4;
            dom+=url[i]; step=2;
        } else if(step == 2) {
            //Stop at subpages, queries, and hashes.
            if(v == '/' || v == '?' || v == '#') break; dom += v;
        }
    }
    return dom;
}
2
Pecacheu

Hier ist der One-Liner von jQuery:

$('<a>').attr('href', url).prop('hostname');
2
gradosevic
// use this if you know you have a subdomain
// www.domain.com -> domain.com
function getDomain() {
  return window.location.hostname.replace(/([a-zA-Z0-9]+.)/,"");
}
1
Gubatron

Nun, es ist viel einfacher, einen regulären Ausdruck zu verwenden:

    mainUrl = "http://www.mywebsite.com/mypath/to/folder";
    urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(mainUrl);
    Host = Fragment[1]; // www.mywebsite.com
1
Saurabh Mandeel

Ich habe viel für diese Lösung recherchiert, und das Beste, was ich finden konnte, ist eigentlich der "Browser-Check" von CloudFlare:

function getHostname(){  
            secretDiv = document.createElement('div');
            secretDiv.innerHTML = "<a href='/'>x</a>";
            secretDiv = secretDiv.firstChild.href;
            var HasHTTPS = secretDiv.match(/https?:\/\//)[0];
            secretDiv = secretDiv.substr(HasHTTPS.length);
            secretDiv = secretDiv.substr(0, secretDiv.length - 1);
            return(secretDiv);  
}  

getHostname();

Ich habe Variablen umgeschrieben, damit sie "leserlich" sind, aber die Aufgabe ist besser als erwartet.

1
Norbert Boros

auf kurze weise kannst du das so machen

var url = "http://www.someurl.com/support/feature"

function getDomain(url){
  domain=url.split("//")[1];
  return domain.split("/")[0];
}
eg:
  getDomain("http://www.example.com/page/1")

  output:
   "www.example.com"

Verwenden Sie die Funktion oben, um den Domainnamen zu erhalten 

0
uzaif

In der Babel-Ära ist die sauberste und einfachste Lösung, die ich gefunden habe, die Verwendung von URL.hostname .

const url = new URL('https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname');
const hostname = url.hostname;
// Returns: 'developer.mozilla.org'

URL.hostname ist Teil der URL-API , die von allen gängigen Browsern mit Ausnahme von IE ( caniuse ) unterstützt wird:

Die URL-Schnittstelle stellt ein Objekt dar, das statische Methoden zum Erstellen von Objekt-URLs bereitstellt.

0
robinmetral