Wie kann ich eine URL testen, wenn es sich um einen relativen oder absoluten Pfad in Javascript oder jQuery handelt? Ich möchte entsprechend behandeln, je nachdem, ob die übergebene URL ein lokaler oder externer Pfad ist.
if (urlString starts with http:// or https://)
//do this
javascript
jquery
string
url
TruMan1
quelle
quelle
//
.SCHNELL
Wenn Sie nur testen müssen
http://
oderhttps://
dann ist der effizienteste Weg:if (urlString.indexOf('http://') === 0 || urlString.indexOf('https://') === 0)
UNIVERSAL
Ich würde jedoch einen universelleren, protokollunabhängigen Ansatz ohne Berücksichtigung der Groß- und Kleinschreibung vorschlagen :
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
Erläutern Sie die RegExp
^(?:[a-z]+:)?//
^
- Beginn der Zeichenfolge(?:
- Beginn einer nicht erfassten Gruppe[a-z]+
- ein beliebiges Zeichen von 'a' bis 'z' 1 oder mehrmals:
- Zeichenfolge (Doppelpunkt))?
- Ende der nicht erfassten Gruppe. Gruppe, die 0 oder 1 Mal erscheint//
- Zeichenfolge (zwei Schrägstriche)'i'
- Flag ohne Berücksichtigung der Groß- und Kleinschreibungquelle
/^(?:[a-z]+:)?\/\//i.test('https://www.ex-maple-123.com');
new RegExp('^(//|[a-z]+:)', 'i')
sollte für die Anpassung arbeitenmailto:
,about:
,tel:
usw. , einschließlich der bestehenden Testfälle. Die Idee hier ist, weiterhin protokollbezogene absolute URLs bereitzustellen und gleichzeitig die vorhandene Funktionalität zum Erkennen absoluter URLs zu erweitern, ohne die doppelten Schrägstriche (//
) überprüfen zu müssen . Somitr.test('mailto:[email protected]') === true
,r.test('https:example.com') === true
und so weiter.Ursprüngliche Antwort
Eine sehr schnelle und sehr flexible Prüfung ist:
if (url.indexOf('://') > 0 || url.indexOf('//') === 0 ) { // URL is absolute; either "http://example.com" or "//example.com" } else { // URL is relative }
Dies erkennt eine absolute URL, wenn:
Update 1 (Vollfunktionsbeispiel)
Hier ist eine kurze Funktion , dass die Renditen true / false für die angegebene URL:
function isUrlAbsolute(url) { return (url.indexOf('://') > 0 || url.indexOf('//') === 0); }
Und dasselbe in ES6:
const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0)
Update 2 (URLs innerhalb des URL-Parameters)
Um URLs zusätzlich im Format zu adressieren,
/redirect?target=http://example.org
empfehle ich, diesen Code zu verwenden: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 }
Und das gleiche in Kurzform und 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)
Hier einige Testfälle:
// 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
Update 3 (relative URLs klären)
Ich habe einige Kommentare zu ungültiger Ausgabe gesehen:
localhost
http:example.com
Diese URLs sind jedoch tatsächlich relative URLs . Es ist einfach zu testen:
quelle
/redirect?target=http://example.org
function isUrlAbsolute(url) { var firstSlash = url.indexOf('/'); var colonDoubleSlash = url.indexOf('://'); return ((firstSlash > 0 && colonDoubleSlash > 0 && colonDoubleSlash < firstSlash) || url.indexOf('//') === 0); }
/redirect?target=http%3A%2F%2Fexample.com
<img src="/aaa/bbb">
Dh wenn Sie auf site1.com und site2.com haben, sind beide Bilder unterschiedlich (dh relativ). Während<img src="//site1.com/aaa/bbb">
ist für alle Domänen identisch (was absolut ist)Verwenden Sie einen regulären Ausdruck:
if (/^(?:[a-z]+:)?\/\//i.test(url))
quelle
mailto:
das manchmal absolut oder relativ sein kann?mailto:
ist absolut, obwohl es keine/
Charaktere hat.Noch mehr universeller RFC-kompatibler URI-Ansatz:
(?:^[a-z][a-z0-9+.-]*:|\/\/)
Regex ErklärungDie anderen hier aufgeführten Lösungen würden für Links wie fehlschlagen
mailto:[email protected]
RFC 3986 definiert ein Schema als:
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
3.1. Schema https://tools.ietf.org/html/rfc3986#section-3.1
Während die protokollbezogene URL gemäß Abschnitt 4.2 technisch gültig ist, hat Paul Irish den umgekehrten Weg eingeschlagen und betrachtet dies als Anti-Muster. Siehe http://www.paulirish.com/2010/the-protocol-relative-url/
4.2. Relative Referenz http://tools.ietf.org/html/rfc3986#section-4.2
Wenn Sie den regulären Ausdruck ohne Verwendung der protokollbezogenen URL möchten:
^[a-z][a-z0-9+.-]*:
Eine vollständige Liste anderer Arten gültiger Uri-Edge-Fälle finden Sie in der Liste hier: https://en.wikipedia.org/wiki/URI_scheme
quelle
^
außerhalb der Gruppe gehen? Wie geschrieben würde es//
in der nicht startenden Position übereinstimmen (also würde eine relative URL wie#//
übereinstimmen). Es ist auch wichtig anzugeben, dass bei diesem regulären Ausdruck die Groß- und Kleinschreibung nicht berücksichtigt werden soll, damit die vollständige Definition wie folgt aussieht/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i
.*
mit+
.Wenn heutzutage viele Dienste eine protokollbezogene URL verwenden (z. B. //cdn.example.com/libary.js ), ist diese Methode sicherer:
var isAbsolute = new RegExp('^([a-z]+://|//)', 'i'); if (isAbsolute.test(urlString)) { // go crazy here }
quelle
'^([A-Za-z]+://|//)'
i
Flag, um den Fall zu ignorieren. Antwort bearbeitet. Vielen Dank.Abhängig von Ihren Anforderungen denke ich, dass eine zuverlässigere Möglichkeit, dies festzustellen, darin besteht, die integrierte URL-Schnittstelle zu verwenden, um einige URL-Objekte zu erstellen und die Ursprünge zu vergleichen.
new URL(document.baseURI).origin === new URL(urlToTest, document.baseURI).origin;
Auf diese Weise kann der Browser all dies für Sie analysieren und herausfinden, ohne sich um die Nebenwirkungen von Randfällen kümmern zu müssen.
quelle
new URL(document.baseURI).origin === new URL(urlToTest,document.baseURI).origin
? Wäre dies nicht passender für Fälle, in denen die Webseite eine enthält<base>
?var external = RegExp('^(https?:)?//'); if(external.test(el)){ // do something }
BEARBEITEN:
Mit dem nächsten regulären Ausdruck können Sie sogar überprüfen, ob der Link zu derselben Domain oder zu einer externen Domain führt:
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')'); if(external.test(el)){ // do something }
quelle
.
Zeichen entkommen, die mit ziemlicher Sicherheit im Hostnamen enthalten sind. Andernfalls stimmt foo.example.com auch mit fooXexample.com übereinVerwenden Sie keine einfachen Dinge wie Regexp usw. Diese Dinge wurden von so vielen anderen Menschen gelöst. Besonders die Randfälle.
Schauen Sie sich URI.js an , es sollte den Job machen: http://medialize.github.io/URI.js/docs.html#is
var uri = new URI("http://example.org/"); uri.is("absolute") === true;
quelle
Hier ist eine ziemlich robuste Lösung für die Browserumgebung:
Lassen Sie den Browser alles erledigen. Es sind keine komplizierten / fehleranfälligen regulären Ausdrücke erforderlich.
const isAbsoluteUrl = (url) => { const link = document.createElement('a'); link.href = url; return link.origin + link.pathname + link.search + link.hash === url; };
quelle
var adress = 'http://roflmao.com'; if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') { // }
quelle
Keine der genannten Lösungen löste einen
redirect_url
Hack, bei dem der Hacker eintrat/\/example.com
oder/\\/example.com
. Folgendes habe ich mir ausgedacht, um festzustellen, ob unsere Weiterleitungs-URL relativ war:var isRelative = !redirectUrl.match(/(\:|\/\\*\/)/); // Don't allow "//" (with optional "\"'s) or ":"
quelle
Die folgende Funktion wird aufgerufen, wenn ein Klickereignis für einen Hyperlink auftritt, dh ein 'a'-Tag. Wenn das Tag eine URL enthält, die relativ ist oder denselben Host enthält, wird diese neue Seite in dieselbe Browserregisterkarte geladen. Wenn sie eine andere URL enthält, wird die Seite geladen in neuer Browser-Registerkarte
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'; } }); });
quelle
Es sollte nicht mit einem Schrägstrich oder Hash beginnen, und es sollte keinen doppelten Schrägstrich enthalten, wenn kein Fragezeichen oder Hash vorangestellt ist. Ich würde das nicht mit einem einzelnen regulären Ausdruck testen, es wäre sehr kompliziert, "kein doppelter Schrägstrich" zu finden.
function test(s) { return s.charAt(0) != "#" && s.charAt(0) != "/" && ( s.indexOf("//") == -1 || s.indexOf("//") > s.indexOf("#") || s.indexOf("//") > s.indexOf("?") ); }
wäre einfacher, klarer und imho schneller.
quelle
Sie können einen try, catch-Block verwenden, um dabei zu helfen. Anstatt einen regulären Ausdruck zu verwenden, können Sie bei jedem Schritt die URL- Schnittstelle verwenden.
isExternalUrl (urlString) { try { const url = new URL(urlString) // THROW ON MISSING SCHEME // DOES THIS URL ORIGINATE FROM THIS WEBSITE? if (url.origin !== new URL(document.URL, document.baseURI).origin) { return true // IS EXTERNAL URL } } catch (_e) { // THROWS WHEN URL DOES NOT HAVE A SCHEME new URL(urlString, document.baseURL) // THROW AN EXCEPTION IF THE URL IS TRULY MALFORMED IN SOME WAY } return false }
quelle
var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;
quelle