Comment tester si une chaîne d'URL est absolue ou relative?

Comment tester une URL s'il s'agit d'un chemin relatif ou absolu en Javascript ou jQuery? Je veux gérer en conséquence selon que L'URL transmise est un chemin local ou externe.

if (urlString starts with http:// or https://)
 //do this
52
demandé sur TruMan1 2012-05-21 18:23:29

11 réponses

var pat = /^https?:\/\//i;
if (pat.test(urlString))
{
    //do stuff
}

pour les urls relatives au protocole, utilisez ce regex:

/^https?:\/\/|^\/\//i

25
répondu strah 2015-04-27 19:25:26

FAST

si vous avez seulement besoin de tester pour http:// ou https:// alors le plus efficace voie est:

if (urlString.indexOf('http://') === 0 || urlString.indexOf('https://') === 0)

universel

cependant, je suggérerais une plus universelle, non cas-sensible, protocole-agnostique approche:

var r = new RegExp('^(?:[a-z]+:)?//', 'i');
r.test('http://example.com'); // true - regular http absolute URL
r.test('HTTP://EXAMPLE.COM'); // true - HTTP upper-case absolute URL
r.test('https://www.exmaple.com'); // true - secure http absolute URL
r.test('ftp://example.com/file.txt'); // true - file transfer absolute URL
r.test('//cdn.example.com/lib.js'); // true - protocol-relative absolute URL
r.test('/myfolder/test.txt'); // false - relative URL
r.test('test'); // false - also relative URL

expliquer le RegExp

^(?:[a-z]+:)?//

^ - début de la chaîne

(?: - début d'un groupe non capturé

[a-z]+ - tout caractère de " a " à " z "1 fois ou plus

: - chaîne (caractère de deux points))

)? - fin du groupe non capturé. Groupe apparaissant 0 ou 1 fois

// - chaîne (deux slash avant) les personnages)

'i' - indicateur non sensible à la casse

116
répondu Geo 2014-02-14 15:13:42

utiliser un regex:

if (/^(?:[a-z]+:)?\/\//i.test(url))
16
répondu SLaks 2013-10-31 15:47:47

Un très rapide et très flexible vérifier est:

if (url.indexOf('://') > 0 || url.indexOf('//') === 0 ) {
    // URL is absolute; either "http://example.com" or "//example.com"
} else {
    // URL is relative
}

cela reconnaîtra une URL absolue, si:

  • l'URL contient "://" n'importe où après le premier caractère, ou
  • URL commence par " / / "(protocol relative)

  • Pas de regex.
  • pas de dépendance jQuery ou autre.
  • aucun nom de protocole codé en dur qui rend la condition sensible à la casse.
  • pas de manipulation de chaîne (par exemple toLowerCase ou similaire).
  • vérifie seulement "relative ou absolue" mais ne fait pas d'autres contrôles de santé mentale, peut être utilisé pour les URLs web ou tout protocole interne.

mise à jour

Voici une fonction rapide qui retourne true / false pour L'URL donnée:

function isUrlAbsolute(url) { 
    return (url.indexOf('://') > 0 || url.indexOf('//') === 0);
}

et même dans ES6:

const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0)

Maj 2

pour adresse URL supplémentaire dans le format /redirect?target=http://example.org je recommande d'utiliser ce code:

function isUrlAbsolute(url) {
    if (url.indexOf('//') === 0) {return true;} // URL is protocol-relative (= absolute)
    if (url.indexOf('://') === -1) {return false;} // URL has no protocol (= relative)
    if (url.indexOf('.') === -1) {return false;} // URL does not contain a dot, i.e. no TLD (= relative, possibly REST)
    if (url.indexOf('/') === -1) {return false;} // URL does not contain a single slash (= relative)
    if (url.indexOf(':') > url.indexOf('/')) {return false;} // The first colon comes after the first slash (= relative)
    if (url.indexOf('://') < url.indexOf('.')) {return true;} // Protocol is defined before first dot (= absolute)
    return false; // Anything else must be relative
}

et les mêmes en forme abrégée et ES 6

// Traditional JS, shortened
function isUrlAbsolute(url) {
    return url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false;
}

// ES 6
const isUrlAbsolute = (url) => (url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false)

voici quelques cases d'essai:

// Test
console.log( isUrlAbsolute('http://stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('//stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('stackoverflow.com') ) // -> false
console.log( isUrlAbsolute('Ftp://example.net') ) // -> true
console.log( isUrlAbsolute('/redirect?target=http://example.org') ) // -> false
8
répondu Philipp 2017-07-24 09:07:00

aujourd'hui, quand un grand nombre de l'utilisation des services de protocole relatif URL (eg. / /cdn.example.com/libary.js ), cette méthode est plus sûre:

var isAbsolute = new RegExp('^([a-z]+://|//)', 'i');

if (isAbsolute.test(urlString)) {
  // go crazy here
}
7
répondu rgtk 2017-05-23 11:33:27

approche URI encore plus universelle conforme à la RFC:

(?:^[a-z][a-z0-9+.-]*:|\/\/) regex explication

les autres solutions énumérées ici échoueraient pour des liens comme mailto:evan@nylas.com

RFC 3986 définit un Scheme comme:

scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )

3.1. Régime https://tools.ietf.org/html/rfc3986#section-3.1

alors que l'url relative au Protocole est techniquement valide selon la section 4.2, Paul Irish s'est retourné dans l'autre sens et considère qu'il s'agit d'un anti-pattern. Voir http://www.paulirish.com/2010/the-protocol-relative-url /

4.2. Référence Relative http://tools.ietf.org/html/rfc3986#section-4.2

si vous souhaitez utiliser regex sans protocole-url relative:

^[a-z][a-z0-9+.-]*:

pour voir la liste complète des autres types d'uri edge valides, consultez la liste ici: https://en.wikipedia.org/wiki/URI_scheme

6
répondu Evan 2015-08-13 15:00:20
var external = RegExp('^(https?:)?//');
if(external.test(el)){
    // do something
}

EDIT:

Avec la prochaine expression régulière, vous pouvez même vérifier si le lien va vers le même domaine ou à l'extérieur:

var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
if(external.test(el)){
    // do something
}
5
répondu davids 2012-05-21 14:29:44

N'utilisez pas de produits de bas niveau comme regexp, etc. Ces choses ont été résolues par tant d'autres personnes. Surtout les cas de bord.

regarder URI.js , il devrait faire le travail: http://medialize.github.io/URI.js/docs.html#is

var uri = new URI("http://example.org/");
uri.is("absolute") === true;
3
répondu koppor 2014-01-30 16:43:36
var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
    //
}
1
répondu OptimusCrime 2012-05-21 14:27:58

la fonction suivante sera appelée lorsque le clic se produit même sur un hyperlien I. e ' a 'tag si la balise contient l'url sera relative ou contient le même hôte alors que la nouvelle page sera chargée dans le même onglet de navigateur si elle contient l'url différente alors la page se chargera dans le nouvel onglet de navigateur

jQuery(document).ready(function() {
    $('a').click(function(){

        var a = this;
        var a_href = $(this).attr('href');
        var regex = new RegExp('^(?:[a-z]+:)?//', 'i');     

        if(a.host == location.host || regex.test(a_href) == false){
            a.target = '_self';
        }else{
            a.target = '_blank';
        }
    }); 
});
1
répondu Prajyot 2015-10-16 15:58:10
var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;
0
répondu rinjan 2016-09-13 15:14:48