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
11 réponses
var pat = /^https?:\/\//i;
if (pat.test(urlString))
{
//do stuff
}
pour les urls relatives au protocole, utilisez ce regex:
/^https?:\/\/|^\/\//i
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
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
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
}
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
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
}
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;
var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
//
}
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';
}
});
});
var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;