path.resolve / path.relative în Node.js

Fișiere și căi (fs, path) Node.js 0.3 (resolve), 0.5 (relative)

Transformă o cale în cale absolută (resolve), calculează drumul dintre două căi (relative) și verifică sau curăță căi.

Sintaxă
import path from "node:path";
path.resolve([...căi])
path.relative(de_la, până_la)
path.isAbsolute(cale)
path.normalize(cale)

Ce face path.resolve / path.relative

path.resolve procesează părțile de la dreapta la stânga până obține o cale absolută. Dacă nicio parte nu este absolută, pornește din directorul curent (process.cwd()). Rezultatul este normalizat și fără / la final.

path.relative(de_la, până_la) întoarce drumul relativ de la prima cale la a doua, de exemplu ../poze/iasi.jpg. Dacă cele două căi sunt identice, întoarce un șir gol.

path.isAbsolute spune dacă o cale este absolută, iar path.normalize curăță o cale (//, ., ..) fără s-o facă absolută. Exemplele folosesc path.posix ca rezultatul să fie același pe orice sistem.

Parametri

Parametru Descriere
...căi Pentru resolve: bucățile căii; ultima parte absolută „resetează” calea.
de_la, până_la Pentru relative: cele două căi; sunt întâi trecute prin resolve.
cale Pentru isAbsolute și normalize: calea verificată sau curățată.

Ce returnează

resolve: cale absolută. relative: cale relativă (sau ""). isAbsolute: true/false. normalize: calea curățată.

Exemple

Exemplul 1: Cum lucrează resolve

import path from "node:path";

const p = path.posix;
console.log(p.resolve("/home/ana", "proiect", "src"));
console.log(p.resolve("/home/ana", "/var/www", "index.html"));
console.log(p.resolve("/home/ana/proiect/", "../poze/"));
console.log(p.normalize("/home//ana/./proiect/../poze"));
console.log(p.isAbsolute("/home/ana"), p.isAbsolute("poze/iasi.jpg"));

Rezultat

/home/ana/proiect/src
/var/www/index.html
/home/ana/poze
/home/ana/poze
true false

Exemplul 2: Drumul dintre două căi: relative

import path from "node:path";

const p = path.posix;
console.log(p.relative("/var/www/site", "/var/www/site/css/stil.css"));
console.log(p.relative("/var/www/site/blog", "/var/www/poze/iasi.jpg"));
console.log(JSON.stringify(p.relative("/var/www", "/var/www")));

const absoluta = path.resolve("rapoarte", "octombrie.csv");
console.log(path.relative(process.cwd(), absoluta));

Rezultat

css/stil.css
../../poze/iasi.jpg
""
rapoarte/octombrie.csv

Exemplul 3: Fișierul cerut rămâne în directorul permis?

Tipar de securitate pentru servere de fișiere: rezolvi calea cerută față de directorul public și verifici că nu iese din el.

import path from "node:path";

const p = path.posix;
const PUBLIC = "/var/www/public";

function caleSigura(ceruta) {
  const completa = p.resolve(PUBLIC, "." + p.sep + ceruta);
  return completa.startsWith(PUBLIC + p.sep) ? completa : null;
}

console.log(caleSigura("poze/iasi.jpg"));
console.log(caleSigura("/css/stil.css"));
console.log(caleSigura("../../etc/passwd"));

Rezultat

/var/www/public/poze/iasi.jpg
/var/www/public/css/stil.css
null

Greșeli frecvente

  • Te aștepți ca resolve("date.json") să pornească din directorul scriptului. Pornește din directorul curent al procesului; pentru directorul scriptului folosește path.resolve(import.meta.dirname, "date.json").
  • Dai o parte care începe cu / la mijloc (resolve(baza, "/poze")) și pierzi tot ce era înainte. Elimină / de la început când calea vine de la utilizator.
  • Verifici ieșirea din director cu startsWith(PUBLIC) fără separator: /var/www/public-vechi ar trece testul. Compară cu PUBLIC + path.sep.

Comenzi înrudite

  • path.join: Lipește mai multe bucăți într-o singură cale, cu separatorul corect pentru sistemul de operare, și curăță ./ și ../.
  • path.parse / path.format / path.sep: Desface o cale în bucăți (root, dir, base, name, ext) și o reface din bucăți; path.sep și path.delimiter dau separatorii sistemului.
  • process.cwd / process.chdir: Directorul curent de lucru al procesului, față de care se rezolvă căile relative. chdir îl schimbă.
  • import.meta.dirname / filename: Calea directorului și a fișierului modulului curent: înlocuitorii pentru __dirname și __filename în module ES.