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