Christian Seiler: relatven Pfad von Link ermitteln.

Beitrag lesen

Hi,

Stringfunktionen bemuehen, um das "unerwuenschte" wegzuschneiden.

Hab ich auch schon dran gedacht. Aber wie wies ich was ich vom absollen Pfad wegschneiden muss um einen relativen zu bekommen?

Naja, Du brauchst, um einen korrekten relativen Pfad zu berechnen, den Ausgangspfad des Dokuments.

Dann kannst Du das z.B. in folgende Funktion packen:

/*  
 * Berechne einen relativen Pfad von quelle nach ziel  
 */  
function berechneRelativenPfad (ziel, quelle) {  
    // wir gehen davon aus, dass es sich hier um absolute URIs  
    // handelt wie bei file, http, https oder ftp  
  
    // zuerst entfernen wir alles was '?' oder '#' beinhaltet  
    var normalisiere = function (zeichenkette) {  
        var i1 = zeichenkette.indexOf ('?');  
        var i2 = zeichenkette.indexOf ('#');  
        if (i1 != -1) {  
            if (i2 != -1 && i2 < i1) {  
                return [zeichenkette.substr (0, i2), zeichenkette.substr (i2)];  
            } else {  
                return [zeichenkette.substr (0, i1), zeichenkette.substr (i1)];  
            }  
        } else if (i2 != -1) {  
            return [zeichenkette.substr (0, i2), zeichenkette.substr (i2)];  
        } else {  
            return [zeichenkette, ''];  
        }  
    }  
  
    quelle = normalisiere (quelle);  
    ziel = normalisiere (ziel);  
    // zuerst trennen wir beide Angaben nach / auf.  
    var zielKomponenten = ziel[0].split ('/');  
    var quellKomponenten = quelle[0].split ('/');  
    // nun sehen wir uns die gleichen komponenten an  
    var i;  
    for (i = 0; i < zielKomponenten.length && i < quellKomponenten.length; i++) {  
        if (zielKomponenten[i] != quellKomponenten[i]) {  
            break;  
        }  
    }  
    // pfade identisch  
    if (i == zielKomponenten.length && i == quellKomponenten.length) {  
        // gib nur anker o.ä. zurück  
        if (ziel[1].length) {  
            return ziel[1];  
        }  
        // Linkziel endet nicht auf /, damit können wir einfach die letzte  
        // Komponente zurückgeben  
        if (zielKomponenten[i-1].length) {  
            return zielKomponenten[i-1];  
        }  
        // Ok, Linkziel endet auf / und ist identisch zur Linkquelle  
        // Also ./ zurückgeben  
        return './';  
    }  
    var ausgabe = '';  
    // suche dir einen Weg zurückn  
    for (var j = i; j < quellKomponenten.length - 1; j++) {  
        ausgabe += '../';  
    }  
    ausgabe += zielKomponenten.slice (i).join ('/');  
    // hänge ?... oder #... noch ran  
    return ausgabe + ziel[1];  
}

Sie ist nicht perfekt - andere Hostnamen erkennt sie zum Beispiel nicht (d.h. wenn es wirklich ein komplett absoluter Link ist). Und man kann das sicher noch eleganter scheiben, das war eher ein Schnellschuss von mir. Aber sie liefert für Links auf dem gleichen Server (oder lokale Links) das korrekte Ergebnis:

js> berechneRelativenPfad ('hallo/die/welt/ist/schoen', 'hallo/das/welt/ist/schoen?b=c/d')  
../../../die/welt/ist/schoen  
js> berechneRelativenPfad ('hallo', 'hallo')  
hallo  
js> berechneRelativenPfad ('hallo?a=b', 'hallo?a=b')  
?a=b  
js> berechneRelativenPfad ('http://de.selfhtml.org/xml/index.htm', 'http://de.selfhtml.org/javascript/index.htm')  
../xml/index.htm

usw. usf.

Viele Grüße,
Christian