¿Existe una forma sencilla de normalizar la ruta del archivo en JavaScript, como en Java tenemos Paths.get("/a/b/../c").normalize() para que /a/../../c se convierta en /c . He visto muchas preguntas iguales aquí, pero son soluciones de Node.js, y necesito un enfoque JS o JQuery puro para que pueda usarse en el navegador.
Tengo un servidor de archivos con interfaz de usuario web, que permite buscar archivos y descargarlos. La interfaz de usuario está escrita en primavera y se puede acceder a ella en mysite.com/ui/
El almacenamiento de archivos se encuentra en mysite.com/files/ que es un directorio simple de Apache, por lo que es posible obtener un enlace directo al archivo.
El directorio de almacenamiento real en el servidor es /var/www/files
La ruta pasa al back-end como mysite.com/ui/?path=/a/../../c , por lo que el back-end normalizará la variable de path por separado a /c y luego la agregará al directorio base y recuperará el contenido de /home/storage/c , por lo que funciona perfectamente.
El problema surge cuando el usuario intenta descargar un archivo como este con un enlace directo. Es decir, si el usuario intenta descargar el archivo /a/../../c/d desde la raíz del servidor de archivos, se agrega a la URL de almacenamiento base, mysite.com/files/ , y se convierte en mysite.com/files/a/../../c/d , por lo que apuntará a /var/www/d en lugar de /var/www/files/d para que el archivo no se pueda descargar incluso si está visible desde la interfaz de usuario web.
Por lo tanto, primero necesito normalizar la ruta del archivo relativo en el front-end como en el back-end al recuperar el contenido del directorio, pero no sé cómo se puede hacer en JS. ¿Hay una función para ello, o tengo que escribir una propia?
Así que terminé escribiendo mi propia función en JS. Puede que no sea lo que significa "normalización de ruta", pero de todos modos es exactamente lo que necesito
function normalizePath(path) { // remove multiple slashes path = path.replace(/\/+/g, '/'); // remove leading slash, will be added further if (path.startsWith("/")) path = path.substring(1) // remove trailing slash if (path.endsWith("/")) path = path.slice(0, -1); let segments = path.split("/"); let normalizedPath = "/"; for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) { if (segments[segmentIndex] === "." || segments[segmentIndex] === "") { // skip single dots and empty segments continue; } if (segments[segmentIndex] === "..") { // go up one level if possible normalizedPath = normalizedPath.substring(0, normalizedPath.lastIndexOf("/") + 1); continue; } // append path segment if (!normalizedPath.endsWith("/")) normalizedPath = normalizedPath + "/" normalizedPath = normalizedPath + segments[segmentIndex]; } return normalizedPath; }Aún así, no marcaré esto como una respuesta aceptada, ya que es más una solución rápida, y no soy un experto en JS, por lo que definitivamente debe ser una solución más elegante.