Node.js ottiene l'estensione del file


209

Sto creando una funzione di caricamento di file in node.js con Express 3.

Vorrei prendere l'estensione del file dell'immagine. così posso rinominare il file e quindi aggiungere l'estensione del file ad esso.

app.post('/upload', function(req, res, next) {
    var is = fs.createReadStream(req.files.upload.path),
        fileExt = '', // I want to get the extension of the image here
        os = fs.createWriteStream('public/images/users/' + req.session.adress + '.' + fileExt);
});

Come posso ottenere l'estensione dell'immagine in node.js?



3
Non è una domanda sui tipi mime, voglio l'estensione del file
georgesamper,

Risposte:


473

Credo che tu possa fare quanto segue per ottenere l'estensione di un nome di file.

var path = require('path')

path.extname('index.html')
// returns
'.html'

54
Fai solo attenzione, afferrerà i caratteri solo dopo l'ultimo punto, quindi i nomi dei file come app.css.gzverranno restituiti .gze non .css.gz, il che potrebbe essere o meno ciò che desideri.
xentek,

18
In tal caso, usa semplicementefilename.split('.').pop();
Aamir Afridi

12
@AamirAfridi Restituisce la stessa stringa senza il ..
indefinito il

13
Cerca 'filename.css.gz'.split('.').slice(1).join('.')di ottenere tutte le estensioni
Trevor,

10
Generalmente l'estensione è l'ultima. E per quando ce ne aspettiamo più di uno, come ad esempio tar.gz. è meglio controllare se esiste alla fine o no. usando ad esempio regex. "tar.gz $" o creando una funzione che lo faccia. come controllarlo dalla fine e tornare indietro e vedere se corrisponde totalmente. e avrai quella funzione che controlla l'estensione. PERCHÉ? perché per quanto riguarda i file come jone.lastTest.654654556.tar.gz qui l'estensione che ci si aspetta è tar.gz ma se si applica una funzione che fornisce il primo punto, non funzionerà come si può vedere
Mohamed Allal,

33

Aggiornare

Dalla risposta originale, extname () è stato aggiunto apath modulo, vedere Risposta di Snowfish

Risposta originale:

Sto usando questa funzione per ottenere un'estensione di file, perché non ho trovato un modo per farlo in modo più semplice (ma penso che ci sia):

function getExtension(filename) {
    var ext = path.extname(filename||'').split('.');
    return ext[ext.length - 1];
}

è necessario richiedere 'percorso' per usarlo.

un altro metodo che non utilizza il modulo path:

function getExtension(filename) {
    var i = filename.lastIndexOf('.');
    return (i < 0) ? '' : filename.substr(i);
}

4
Sì, funziona. Ho pensato che ci sarebbe stato un modo più semplice usando il nodo. Questo è quello che ho fatto:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
georgesamper

6
Dovresti semplicemente usare il modulo path, come ha sottolineato la risposta di @ Snowfish, e non scrivere il tuo. Ulteriori informazioni: nodejs.org/api/path.html#path_path_extname_p
xentek

e che dire quando i file non mostrano le estensioni ??
Vecchio

19
// you can send full url here
function getExtension(filename) {
    return filename.split('.').pop();
}

Se si utilizza express, aggiungere la seguente riga durante la configurazione del middleware (bodyParser)

app.use(express.bodyParser({ keepExtensions: true}));

12

È molto più efficiente utilizzare il substr()metodo invece di split()&pop()

Dai un'occhiata alle differenze di prestazioni qui: http://jsperf.com/remove-first-character-from-string

// returns: 'html'
var path = require('path');
path.extname('index.html').substr(1);

inserisci qui la descrizione dell'immagine

Aggiornamento agosto 2019 Come sottolineato da @xentek nei commenti; substr()è ora considerata una funzione legacy ( documentazione MDN ). Puoi usare substring()invece. La differenza tra substr()e substring()è che il secondo argomento di substr()è la lunghezza massima da restituire mentre il secondo argomento di substring()è l'indice a cui fermarsi (senza includere quel carattere). Inoltre, substr()accetta posizioni di inizio negative da utilizzare come offset dalla fine della stringa, mentre substring()non lo fa.


C'è un avviso ora substrperché è considerata una funzione legacy e dovrebbe essere evitata quando possibile - Ulteriori informazioni su MDN
Core972

Quando si esegue il test substr (1), è necessario prendere in considerazione anche il tempo impiegato per path.extname
eugenekr

11

Questa soluzione supporta le stringhe di querys!

var Url = require('url');
var Path = require('path');

var url = 'http://i.imgur.com/Mvv4bx8.jpg?querystring=true';
var result = Path.extname(Url.parse(url).pathname); // '.jpg'

6

Una soluzione semplice senza necessità che risolve il problema dell'estensione di più periodi:

var filename = 'file.with.long.extension';
var ext = filename.substring(filename.indexOf('.')); 
//ext = '.with.long.extension'

O se non vuoi il punto iniziale:

var filename = 'file.with.long.extension';
var ext = filename.substring(filename.indexOf('.')+1); 
//ext = 'with.long.extension'

Assicurati di verificare che anche il file abbia un'estensione.


4

Penso che anche la mappatura dell'intestazione Content-Type nella richiesta funzionerà. Questo funzionerà anche per i casi in cui carichi un file senza estensione. (quando il nome file non ha un'estensione nella richiesta)

Supponi di inviare i tuoi dati utilizzando HTTP POST:

POST /upload2 HTTP/1.1
Host: localhost:7098
Connection: keep-alive
Content-Length: 1047799
Accept: */*
Origin: http://localhost:63342
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,    like Gecko) Chrome/51.0.2704.106 Safari/537.36
Content-Type: multipart/form-data; boundary=----   WebKitFormBoundaryPDULZN8DYK3VppPp
Referer: http://localhost:63342/Admin/index.html? _ijt=3a6a054pasorvrljf8t8ea0j4h
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,az;q=0.6,tr;q=0.4
Request Payload
------WebKitFormBoundaryPDULZN8DYK3VppPp
Content-Disposition: form-data; name="image"; filename="blob"
Content-Type: image/png


------WebKitFormBoundaryPDULZN8DYK3VppPp--

Qui il nome dell'intestazione Content-Type contiene il tipo mime dei dati. La mappatura di questo tipo MIME su un'estensione ti darà l'estensione del file :).

Restify BodyParser converte questa intestazione in una proprietà con tipo di nome

File {
  domain: 
   Domain {
     domain: null,
     _events: { .... },
     _eventsCount: 1,
     _maxListeners: undefined,
     members: [ ... ] },
  _events: {},
  _eventsCount: 0,
  _maxListeners: undefined,
  size: 1047621,
  path: '/tmp/upload_2a4ac9ef22f7156180d369162ef08cb8',
  name: 'blob',
  **type: 'image/png'**,
  hash: null,
  lastModifiedDate: Wed Jul 20 2016 16:12:21 GMT+0300 (EEST),
  _writeStream: 
  WriteStream {
   ... },
     writable: true,
     domain: 
     Domain {
        ...
     },
      _events: {},
      _eventsCount: 0,
     _maxListeners: undefined,
     path: '/tmp/upload_2a4ac9ef22f7156180d369162ef08cb8',
     fd: null,
     flags: 'w',
     mode: 438,
     start: undefined,
     pos: undefined,
     bytesWritten: 1047621,
     closed: true } 
}

È possibile utilizzare questa intestazione ed eseguire manualmente la mappatura dell'estensione (sottostringa ecc ...), ma per questo ci sono anche librerie già pronte. Sotto due sono stati i risultati migliori quando ho fatto una ricerca su Google

  • mimo
  • mime-type

e anche il loro utilizzo è semplice:

 app.post('/upload2', function (req, res) {
  console.log(mime.extension(req.files.image.type));
 }

sopra lo snippet stamperà png sulla console.


2
var fileName = req.files.upload.name;

var arr = fileName.split('.');

var extension = arr[length-1];

1
da dove viene la variabile di lunghezza?
Angel S. Moreno,

3
Prova ad aggiungere qualche spiegazione alla tua risposta. In questo modo, l'OP può effettivamente capire cosa hai fatto e perché l'hai fatto. In questo modo l'OP può imparare dalla tua risposta, piuttosto che semplicemente copiarla / incollarla.
Oldskool,

1

path.extnamefarà il trucco nella maggior parte dei casi. Tuttavia, includerà tutto dopo l'ultimo ., compresa la stringa di query e il frammento di hash di una richiesta http:

var path = require('path')
var extname = path.extname('index.html?username=asdf')
// extname contains '.html?username=asdf'

In tali casi, ti consigliamo di provare qualcosa del genere:

var regex = /[#\\?]/g; // regex of illegal extension characters
var extname = path.extname('index.html?username=asdf');
var endOfExt = extname.search(regex);
if (endOfExt > -1) {
    extname = extname.substring(0, endOfExt);
}
// extname contains '.html'

Tieni presente che le estensioni con più periodi (come .tar.gz) non funzioneranno affatto path.extname.


0

La seguente funzione divide la stringa e restituisce il nome e l'estensione, indipendentemente dal numero di punti presenti nell'estensione. Restituisce una stringa vuota per l'estensione se non ce n'è. Anche i nomi che iniziano con punti e / o spazi bianchi funzionano.

function basext(name) {
  name = name.trim()
  const match = name.match(/^(\.+)/)
  let prefix = ''
  if (match) {
    prefix = match[0]
    name = name.replace(prefix, '')
  }
  const index = name.indexOf('.')
  const ext = name.substring(index + 1)
  const base = name.substring(0, index) || ext
  return [prefix + base, base === ext ? '' : ext]
}

const [base, ext] = basext('hello.txt')

0

import extname per restituire l'estensione al file:

import { extname } from 'path';
extname(file.originalname);

dove file è il 'nome' del file del modulo


0

È possibile utilizzare path.parse (percorso) , ad esempio

const path = require('path');
const { ext } = path.parse('/home/user/dir/file.txt');

0

Prova questo

const path = require('path');

function getExt(str) {
  const basename = path.basename(str);
  const firstDot = basename.indexOf('.');
  const lastDot = basename.lastIndexOf('.');
  const extname = path.extname(basename).replace(/(\.[a-z0-9]+).*/i, '$1');

  if (firstDot === lastDot) {
    return extname;
  }

  return basename.slice(firstDot, lastDot) + extname;
}

// all are `.gz`
console.log(getExt('/home/charlike/bar/file.gz'));
console.log(getExt('/home/charlike/bar/file.gz~'));
console.log(getExt('/home/charlike/bar/file.gz+cdf2'));
console.log(getExt('/home/charlike/bar/file.gz?quz=zaz'));

// all are `.tar.gz`
console.log(getExt('/home/charlike/bar/file.tar.gz'));
console.log(getExt('/home/charlike/bar/file.tar.gz~'));
console.log(getExt('/home/charlike/bar/file.tar.gz+cdf2'));
console.log(getExt('/home/charlike/bar/file.tar.gz?quz=zaz'));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.