Extension de fichier Node.js get


210

Je crée une fonction de téléchargement de fichiers dans node.js avec express 3.

Je voudrais saisir l'extension de fichier de l'image. afin que je puisse renommer le fichier, puis y ajouter l'extension.

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);
});

Comment puis-je obtenir l'extension de l'image dans node.js?



3
N'est-ce pas une question sur les types
MIME

Réponses:


473

Je pense que vous pouvez faire ce qui suit pour obtenir l'extension d'un nom de fichier.

var path = require('path')

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

54
Faites juste attention, il ne saisira que les caractères après le dernier point, donc les noms de fichiers comme app.css.gzne reviendront que .gzet non .css.gz, ce qui peut ou non être ce que vous voulez.
xentek

18
Dans ce cas, utilisez simplementfilename.split('.').pop();
Aamir Afridi

12
@AamirAfridi Cela renvoie la même chaîne juste sans le ..
indéfini

13
Essayez 'filename.css.gz'.split('.').slice(1).join('.')d'obtenir toutes les extensions
Trevor

10
Généralement, l'extension est la dernière. Et quand nous en attendons plus d'un, comme tar.gz par exemple. il vaut mieux vérifier s'il existe ou non à la fin. en utilisant regex par exemple. "tar.gz $" ou en créant une fonction qui fait cela. comme vérifier cela à la fin et revenir en arrière et voir si cela correspond totalement. et vous aurez cette fonction qui vérifie l'extension. POURQUOI? car qu'en est-il des fichiers comme jone.lastTest.654654556.tar.gz ici, l'extension qui est attendue est tar.gz mais si vous appliquez une fonction qui donne la forme du premier point, cela ne fonctionnera pas comme vous pouvez le voir
Mohamed Allal

33

Mettre à jour

Depuis la réponse d'origine, extname () a été ajouté au pathmodule, voir la réponse de Snowfish

Réponse originale:

J'utilise cette fonction pour obtenir une extension de fichier, car je n'ai pas trouvé de moyen de le faire plus facilement (mais je pense qu'il y en a un):

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

vous devez avoir besoin de 'path' pour l'utiliser.

une autre méthode qui n'utilise pas le module de chemin:

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

4
Ouais ça marche. Je pensais simplement qu'il y aurait un moyen plus simple d'utiliser node. Voici ce que j'ai fait:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
georgesamper

6
Vous devriez vraiment simplement utiliser le module de chemin, comme l'a souligné la réponse de @ Snowfish, et ne pas écrire le vôtre. Plus d'informations: nodejs.org/api/path.html#path_path_extname_p
xentek

et qu'en est-il lorsque les fichiers ne présentent pas d'extensions ??
Oldboy

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

Si vous utilisez express, veuillez ajouter la ligne suivante lors de la configuration du middleware (bodyParser)

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

12

Il est beaucoup plus efficace d'utiliser la substr()méthode au lieu de split()&pop()

Jetez un œil aux différences de performances ici: http://jsperf.com/remove-first-character-from-string

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

entrez la description de l'image ici

Mise à jour d'août 2019 Comme l'a souligné @xentek dans les commentaires; substr()est désormais considérée comme une fonction héritée ( documentation MDN ). Vous pouvez utiliser à la substring()place. La différence entre substr()et substring()est que le deuxième argument de substr()est la longueur maximale à renvoyer tandis que le deuxième argument de substring()est l'indice où s'arrêter (sans inclure ce caractère). En outre, substr()accepte les positions de départ négatives à utiliser comme décalage par rapport à la fin de la chaîne tandis substring()que non.


Il y a maintenant un avertissement car substril est considéré comme une fonction héritée et doit être évité lorsque cela est possible - Plus d'informations sur MDN
Core972

Lors du test de substr (1), vous devez également prendre en compte le temps passé pour path.extname
eugenekr

11

Cette solution prend en charge les querystrings!

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

Une solution simple sans besoin d'exigence qui résout le problème d'extension de plusieurs périodes:

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

Ou si vous ne voulez pas le premier point:

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

Assurez-vous de tester que le fichier a également une extension.


4

Je pense que le mappage de l'en-tête Content-Type dans la demande fonctionnera également. Cela fonctionnera même dans les cas où vous téléchargez un fichier sans extension. (lorsque le nom de fichier n'a pas d'extension dans la demande)

Supposons que vous envoyez vos données à l'aide de 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--

Ici, l'en-tête Content-Type contient le type MIME des données. Le mappage de ce type MIME à une extension vous donnera l'extension de fichier :).

Restify BodyParser convertit cet en-tête en une propriété de type nom

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 } 
}

Vous pouvez utiliser cet en-tête et faire le mappage d'extension (sous-chaîne, etc.) manuellement, mais il existe également des bibliothèques prêtes à l'emploi pour cela. Ci-dessous deux étaient les meilleurs résultats quand j'ai fait une recherche google

  • mime
  • types mime

et leur utilisation est également simple:

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

l'extrait ci-dessus imprimera le png sur la console.


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

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

var extension = arr[length-1];

1
d'où vient la variable de longueur?
Angel S. Moreno,

3
Essayez d'ajouter quelques explications à votre réponse. De cette façon, le PO peut réellement comprendre ce que vous avez fait et pourquoi vous l'avez fait. De cette façon, le PO peut apprendre de votre réponse, plutôt que de simplement le copier / coller.
Oldskool

1

path.extnamefera l'affaire dans la plupart des cas. Cependant, il inclura tout après le dernier ., y compris la chaîne de requête et le fragment de hachage d'une demande http:

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

Dans de tels cas, vous voudrez essayer quelque chose comme ceci:

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'

Notez que les extensions avec plusieurs périodes (comme .tar.gz) ne fonctionneront pas du tout avec path.extname.


0

La fonction suivante fractionne la chaîne et renvoie le nom et l'extension quel que soit le nombre de points dans l'extension. Il renvoie une chaîne vide pour l'extension s'il n'y en a pas. Les noms commençant par des points et / ou des espaces blancs fonctionnent également.

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

importez extname afin de renvoyer l'extension du fichier:

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

où fichier est le nom du fichier du formulaire


0

Vous pouvez utiliser path.parse (path) , par exemple

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

0

Essaye celui-là

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'));
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.