Es gibt eine Funktion, die mir URLs gibt wie:
./some.css
./extra/some.css
../../lib/slider/slider.css
Es ist immer ein relativer Weg.
Nehmen wir an, wir kennen den aktuellen Pfad der Seite und wissen http://site.com/stats/2012/
nicht, wie ich diese relativen Pfade in echte konvertieren soll.
Wir sollten so etwas bekommen wie:
./some.css => http://site.com/stats/2012/some.css
./extra/some.css => http://site.com/stats/2012/extra/some.css
../../lib/slider/slider.css => http://site.com/lib/slider/slider.css
Keine jQuery, nur Vanille-Javascript.
javascript
html
path
Jaspis
quelle
quelle
Antworten:
Dies sollte es tun:
function absolute(base, relative) { var stack = base.split("/"), parts = relative.split("/"); stack.pop(); // remove current file name (or empty string) // (omit if "base" is the current folder without trailing slash) for (var i=0; i<parts.length; i++) { if (parts[i] == ".") continue; if (parts[i] == "..") stack.pop(); else stack.push(parts[i]); } return stack.join("/"); }
quelle
~
,~/media/style.css
, läuft in diesen den anderen Tag~
bedeutet normalerweise etwas anderes alsbase
. Und es ist nicht gerade ein relativer Pfad :-) Wenn Sie Hilfe bei Pfaden benötigen, die eine Tilde enthalten, stellen Sie bitte eine neue Frage/
beispielsweise mit a beginnt/some.css
. Eine korrekte Implementierung würde in einem solchen Fall alle Elemente im Stapel nach dem Domänennamen entfernen./
nicht relativ. Meine Funktion berücksichtigt nur Pfade, keine URIs.Der einfachste, effizienteste und korrekteste Weg, dies zu tun, ist die Verwendung der URL- API.
new URL("http://www.stackoverflow.com?q=hello").href; //=> http://www.stackoverflow.com/?q=hello" new URL("mypath","http://www.stackoverflow.com").href; //=> "http://www.stackoverflow.com/mypath" new URL("../mypath","http://www.stackoverflow.com/search").href //=> "http://www.stackoverflow.com/mypath" new URL("../mypath", document.baseURI).href //=> "/programming/mypath"
In Bezug auf die Leistung ist diese Lösung mit der Verwendung von String-Manipulationen vergleichbar und doppelt so schnell wie das Erstellen von
a
Tags.quelle
window.location.href
diesen Nachteil hat. Ich habe die Antwort so bearbeitet, dass siedocument.baseURI
stattdessen verwendet wird.Javascript erledigt das für Sie. Es ist nicht erforderlich, eine Funktion zu erstellen.
var link = document.createElement("a"); link.href = "../../lib/slider/slider.css"; alert(link.protocol+"//"+link.host+link.pathname+link.search+link.hash); // Output will be "http://www.yoursite.com/lib/slider/slider.css"
Aber wenn Sie es als Funktion brauchen:
var absolutePath = function(href) { var link = document.createElement("a"); link.href = href; return (link.protocol+"//"+link.host+link.pathname+link.search+link.hash); }
Update: Einfachere Version, wenn Sie den vollständigen absoluten Pfad benötigen:
var absolutePath = function(href) { var link = document.createElement("a"); link.href = href; return link.href; }
quelle
link.href
nach dem Festlegen die aufgelöste URL zurückgegeben wird (dh die href muss nicht manuell neu erstellt werden).Dies von MDN ist unzerbrechlich!
/*\ |*| |*| :: translate relative paths to absolute paths :: |*| |*| https://developer.mozilla.org/en-US/docs/Web/API/document.cookie |*| |*| The following code is released under the GNU Public License, version 3 or later. |*| http://www.gnu.org/licenses/gpl-3.0-standalone.html |*| \*/ function relPathToAbs (sRelPath) { var nUpLn, sDir = "", sPath = location.pathname.replace(/[^\/]*$/, sRelPath.replace(/(\/|^)(?:\.?\/+)+/g, "$1")); for (var nEnd, nStart = 0; nEnd = sPath.indexOf("/../", nStart), nEnd > -1; nStart = nEnd + nUpLn) { nUpLn = /^\/(?:\.\.\/)*/.exec(sPath.slice(nEnd))[0].length; sDir = (sDir + sPath.substring(nStart, nEnd)).replace(new RegExp("(?:\\\/+[^\\\/]*){0," + ((nUpLn - 1) / 3) + "}$"), "/"); } return sDir + sPath.substr(nStart); }
Beispielnutzung:
/* Let us be in /en-US/docs/Web/API/document.cookie */ alert(location.pathname); // displays: /en-US/docs/Web/API/document.cookie alert(relPathToAbs("./")); // displays: /en-US/docs/Web/API/ alert(relPathToAbs("../Guide/API/DOM/Storage")); // displays: /en-US/docs/Web/Guide/API/DOM/Storage alert(relPathToAbs("../../Firefox")); // displays: /en-US/docs/Firefox alert(relPathToAbs("../Guide/././API/../../../Firefox")); // displays: /en-US/docs/Firefox
quelle
/
. Beispiel:relPathToAbs("/?foo=bar")
sollte stattdessen "/? Foo = bar" zurückgeben,/questions/14780350/?foo=bar
was bedeutet, dass ein Lead nicht richtig erkannt wird,/
wenn der Pfad zurück zum Stamm gesendet wird.http(s)://
) und den Such- / Hash- Segmenten (?
/#
) enthalten ist. Es ist nicht Anliegen dieser Funktion die trennen Pfad Teil von den Such / Hash - Teilen, auch weil Reguläre Ausdrücke können es machen sehr einfach:relPathToAbs("./?foo=bar#someHash".replace(/^[^\?#]*/, "$&"))
/
ist bereits ein absoluter Pfad! Daher macht es keinen Sinn, es als Argument für diese Funktion zu verwenden! Die Zeichenfolge"/?foo=bar"
ist bereits ein absoluter Pfad.relPathToAbs("/?foo=bar")
. Es kehrt nicht zurück/?foo=bar
(weil es bereits absolut ist), es kehrt zurück/questions/14780350/?foo=bar
./?foo=bar
ist ein falscher relativer Pfad (tatsächlich ist es ein absoluter Pfad). Ein gültiger relativer Pfad muss mit beginnen/^(?:\.\.?\/)*[^\/]/
. ZB:/^(?:\.\.?\/)*[^\/]/.test("./hello/world")
->true
;/^(?:\.\.?\/)*[^\/]/.test("../hi")
->true
;/^(?:\.\.?\/)*[^\/]/.test("../././../foo")
->true
;/^(?:\.\.?\/)*[^\/]/.test("/")
->false
;/^(?:\.\.?\/)*[^\/]/.test("/?foo=bar")
->false
;Wenn Sie eine Relation von relativ zu absolut für einen Link von einer benutzerdefinierten Webseite in Ihrem Browser durchführen möchten (nicht für die Seite, auf der Ihr Skript ausgeführt wird), können Sie eine erweiterte Version der von @Bergi vorgeschlagenen Funktion verwenden:
var resolveURL=function resolve(url, base){ if('string'!==typeof url || !url){ return null; // wrong or empty url } else if(url.match(/^[a-z]+\:\/\//i)){ return url; // url is absolute already } else if(url.match(/^\/\//)){ return 'http:'+url; // url is absolute already } else if(url.match(/^[a-z]+\:/i)){ return url; // data URI, mailto:, tel:, etc. } else if('string'!==typeof base){ var a=document.createElement('a'); a.href=url; // try to resolve url without base if(!a.pathname){ return null; // url not valid } return 'http://'+url; } else{ base=resolve(base); // check base if(base===null){ return null; // wrong base } } var a=document.createElement('a'); a.href=base; if(url[0]==='/'){ base=[]; // rooted path } else{ base=a.pathname.split('/'); // relative path base.pop(); } url=url.split('/'); for(var i=0; i<url.length; ++i){ if(url[i]==='.'){ // current directory continue; } if(url[i]==='..'){ // parent directory if('undefined'===typeof base.pop() || base.length===0){ return null; // wrong url accessing non-existing parent directories } } else{ // child directory base.push(url[i]); } } return a.protocol+'//'+a.hostname+base.join('/'); }
Es wird zurückkehren,
null
wenn etwas nicht stimmt.Verwendung:
resolveURL('./some.css', 'http://example.com/stats/2012/'); // returns http://example.com/stats/2012/some.css resolveURL('extra/some.css', 'http://example.com/stats/2012/'); // returns http://example.com/stats/2012/extra/some.css resolveURL('../../lib/slider/slider.css', 'http://example.com/stats/2012/'); // returns http://example.com/lib/slider/slider.css resolveURL('/rootFolder/some.css', 'https://example.com/stats/2012/'); // returns https://example.com/rootFolder/some.css resolveURL('localhost'); // returns http://localhost resolveURL('../non_existing_file', 'example.com') // returns null
quelle
function canonicalize(url) { var div = document.createElement('div'); div.innerHTML = "<a></a>"; div.firstChild.href = url; // Ensures that the href is properly escaped div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser return div.firstChild.href; }
Dies funktioniert im Gegensatz zu einigen anderen Lösungen auch unter IE6 (siehe Abrufen einer absoluten URL von einer relativen URL (IE6-Problem) ).
quelle
Die vorgeschlagene und akzeptierte Lösung unterstützt keine serverbezogenen URLs und funktioniert nicht mit absoluten URLs. Wenn mein Verwandter / sites / folder1 ist, funktioniert das zum Beispiel nicht.
Hier ist eine weitere Funktion, die vollständige, serverbezogene oder relative URLs sowie ../ für eine Ebene höher unterstützt. Es ist nicht perfekt, deckt aber viele Optionen ab. Verwenden Sie diese Option, wenn Ihre Basis-URL nicht die aktuelle Seiten-URL ist. Andernfalls gibt es bessere Alternativen.
function relativeToAbsolute(base, relative) { //make sure base ends with / if (base[base.length - 1] != '/') base += '/'; //base: https://server/relative/subfolder/ //url: https://server let url = base.substr(0, base.indexOf('/', base.indexOf('//') + 2)); //baseServerRelative: /relative/subfolder/ let baseServerRelative = base.substr(base.indexOf('/', base.indexOf('//') + 2)); if (relative.indexOf('/') === 0)//relative is server relative url += relative; else if (relative.indexOf("://") > 0)//relative is a full url, ignore base. url = relative; else { while (relative.indexOf('../') === 0) { //remove ../ from relative relative = relative.substring(3); //remove one part from baseServerRelative. /relative/subfolder/ -> /relative/ if (baseServerRelative !== '/') { let lastPartIndex = baseServerRelative.lastIndexOf('/', baseServerRelative.length - 2); baseServerRelative = baseServerRelative.substring(0, lastPartIndex + 1); } } url += baseServerRelative + relative;//relative is a relative to base. } return url; }
Hoffe das hilft. Es war wirklich frustrierend, dieses grundlegende Dienstprogramm nicht in JavaScript verfügbar zu haben.
quelle
//www.example.com/page
.Die href-Lösung funktioniert nur, wenn das Dokument geladen ist (zumindest in IE11). Das hat bei mir funktioniert:
link = link || document.createElement("a"); link.href = document.baseURI + "/../" + href; return link.href;
Siehe https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
quelle
document.baseURI
stattdessenwindow.location.href
verwenden, um ein mögliches<base>
Element zu berücksichtigen .Ich musste der akzeptierten Lösung einen Fix hinzufügen, da wir in unserer Angularjs-Navigation Schrägstriche nach # haben können.
function getAbsoluteUrl(base, relative) { // remove everything after # var hashPosition = base.indexOf('#'); if (hashPosition > 0){ base = base.slice(0, hashPosition); } // the rest of the function is taken from http://stackoverflow.com/a/14780463 // http://stackoverflow.com/a/25833886 - this doesn't work in cordova // http://stackoverflow.com/a/14781678 - this doesn't work in cordova var stack = base.split("/"), parts = relative.split("/"); stack.pop(); // remove current file name (or empty string) // (omit if "base" is the current folder without trailing slash) for (var i=0; i<parts.length; i++) { if (parts[i] == ".") continue; if (parts[i] == "..") stack.pop(); else stack.push(parts[i]); } return stack.join("/"); }
quelle
if (charAt(0) !== ".") return relative;
, um den Fall zu behandeln, in demrelative
bereits ein absoluter Pfad vorhanden ist, sodass ich nicht zuerst prüfen muss, ob er relativ ist, bevor ich diese Funktion aufrufe.Ich habe eine sehr einfache Lösung gefunden, um dies zu tun, während ich IE 10 (IE unterstützt die URL-API nicht) mithilfe der Verlaufs-API (IE 10 oder höher) unterstütze. Diese Lösung funktioniert ohne String-Manipulation.
function resolveUrl(relativePath) { var originalUrl = document.location.href; history.replaceState(history.state, '', relativePath); var resolvedUrl = document.location.href; history.replaceState(history.state, '', originalUrl); return resolvedUrl; }
history.replaceState()
document.location
Löst keine Browsernavigation aus, ändert jedoch relative und absolute Pfade und unterstützt diese.Der einzige Nachteil dieser Lösung ist, dass der Titel des aktuellen Status verloren geht, wenn Sie bereits die Verlaufs-API verwenden und einen benutzerdefinierten Status mit einem Titel festgelegt haben.
quelle
Das wird funktionieren. aber nur, wenn Sie eine Seite mit dem Dateinamen öffnen. Es wird nicht gut funktionieren, wenn Sie einen Link wie diesen öffnen
stackoverflow.com/page
. es wird funktionieren mitstackoverflow.com/page/index.php
function reltoabs(link){ let absLink = location.href.split("/"); let relLink = link; let slashesNum = link.match(/[.]{2}\//g) ? link.match(/[.]{2}\//g).length : 0; for(let i = 0; i < slashesNum + 1; i++){ relLink = relLink.replace("../", ""); absLink.pop(); } absLink = absLink.join("/"); absLink += "/" + relLink; return absLink; }
quelle