Node.js erhält Dateierweiterung


209

Ich erstelle eine Datei-Upload-Funktion in node.js mit Express 3.

Ich möchte die Dateierweiterung des Bildes greifen. so kann ich die Datei umbenennen und dann die Dateierweiterung an sie anhängen.

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

Wie kann ich die Erweiterung des Bildes in node.js erhalten?



3
Ist das nicht eine Frage zu MIME-Typen, ich möchte die Dateierweiterung
Georgesamper

Antworten:


472

Ich glaube, Sie können Folgendes tun, um die Erweiterung eines Dateinamens zu erhalten.

var path = require('path')

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

54
Seien Sie nur vorsichtig, es werden nur die Zeichen nach dem letzten Punkt erfasst, sodass Dateinamen wie app.css.gznur zurückgegeben werden .gzund nicht .css.gz, was möglicherweise das ist, was Sie wollen oder nicht.
Xentek

18
In diesem Fall verwenden Sie einfachfilename.split('.').pop();
Aamir Afridi

12
@AamirAfridi Das gibt den gleichen String nur ohne das zurück ..
undefiniert

13
Versuchen Sie 'filename.css.gz'.split('.').slice(1).join('.'), alle Erweiterungen zu bekommen
Trevor

10
Im Allgemeinen ist die Erweiterung die letzte. Und wenn wir mehr als eine erwarten, wie zum Beispiel tar.gz. Es ist besser zu überprüfen, ob es am Ende existiert oder nicht. zum Beispiel mit Regex. "tar.gz $" oder durch Aufbau einer Funktion, die dies tut. wie das vom Ende zu überprüfen und zurück zu gehen und zu sehen, ob es total übereinstimmt. und Sie haben diese Funktion, die die Erweiterung überprüft. WARUM? denn was ist mit Dateien wie jone.lastTest.654654556.tar.gz hier? Die erwartete Erweiterung ist tar.gz, aber wenn Sie eine Funktion anwenden, die das Formular 1. Punkt ergibt, funktioniert es nicht, wie Sie sehen können
Mohamed Allal

33

Aktualisieren

Da die ursprüngliche Antwort extname () zum pathModul hinzugefügt wurde , siehe Antwort von Snowfish

Ursprüngliche Antwort:

Ich verwende diese Funktion, um eine Dateierweiterung zu erhalten, da ich keinen einfacheren Weg gefunden habe (aber ich denke, dass es einen gibt):

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

Sie müssen 'Pfad' benötigen, um es zu verwenden.

eine andere Methode, die das Pfadmodul nicht verwendet:

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

4
Ja das funktioniert. Ich dachte nur, es gäbe einen einfacheren Weg, Knoten zu verwenden. Dies ist, was ich getan habe:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
Georgesamper

6
Sie sollten wirklich nur das Pfadmodul verwenden, wie in der Antwort von @ Snowfish hervorgehoben, und nicht Ihr eigenes schreiben. Weitere Informationen: nodejs.org/api/path.html#path_path_extname_p
xentek

und was ist, wenn die Dateien keine Erweiterungen anzeigen?
Oldboy

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

Wenn Sie Express verwenden, fügen Sie bei der Konfiguration der Middleware (bodyParser) die folgende Zeile hinzu.

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

12

Es ist viel effizienter, die substr()Methode anstelle von split()& zu verwendenpop()

Schauen Sie sich die Leistungsunterschiede hier an: http://jsperf.com/remove-first-character-from-string

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

Geben Sie hier die Bildbeschreibung ein

Update August 2019 Wie von @xentek in den Kommentaren ausgeführt; substr()wird jetzt als Legacy-Funktion betrachtet ( MDN-Dokumentation ). Sie können substring()stattdessen verwenden. Der Unterschied zwischen substr()und substring()besteht darin, dass das zweite Argument von substr()die maximale Länge ist, die zurückgegeben werden soll, während das zweite Argument von substring()der Index ist, bei dem angehalten werden soll (ohne dieses Zeichen einzuschließen). Auch substr()akzeptiert negative Startpositionen verwendet werden , wie ein vom Ende des Strings versetzt , während substring()dies nicht tut.


Es gibt jetzt eine Warnung, da substres sich um eine Legacy-Funktion handelt und nach Möglichkeit vermieden werden sollte. Weitere Informationen zu MDN
Core972

Wenn Sie den substr (1) -Test durchführen, sollten Sie auch die Zeit berücksichtigen, die für path.extname
eugenekr

11

Diese Lösung unterstützt Querystringe!

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

Eine einfache Lösung ohne Notwendigkeit, die das Problem der Verlängerung um mehrere Perioden löst:

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

Oder wenn Sie den führenden Punkt nicht möchten:

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

Stellen Sie sicher, dass Sie testen, ob die Datei auch eine Erweiterung hat.


4

Ich denke, dass das Zuordnen des Content-Type-Headers in der Anfrage auch funktionieren wird. Dies funktioniert auch in Fällen, in denen Sie eine Datei ohne Erweiterung hochladen. (wenn der Dateiname keine Erweiterung in der Anfrage hat)

Angenommen, Sie senden Ihre Daten über 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--

Hier enthält der Name Content-Type-Header den MIME-Typ der Daten. Wenn Sie diesen MIME-Typ einer Erweiterung zuordnen, erhalten Sie die Dateierweiterung :).

Restify BodyParser wandelt diesen Header in einer Eigenschaft mit dem Namen Typ

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

Sie können diesen Header verwenden und die Erweiterungszuordnung (Teilzeichenfolge usw.) manuell durchführen. Hierfür gibt es jedoch auch vorgefertigte Bibliotheken. Unter zwei waren die Top-Ergebnisse, als ich eine Google-Suche durchgeführt habe

  • Mime
  • Pantomime-Typen

und ihre Verwendung ist ebenfalls einfach:

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

Über dem Snippet wird PNG auf der Konsole gedruckt .


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

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

var extension = arr[length-1];

1
Woher kommt die Längenvariable?
Angel S. Moreno

3
Versuchen Sie, Ihrer Antwort eine Erklärung hinzuzufügen. Auf diese Weise kann das OP tatsächlich verstehen, was Sie getan haben und warum Sie dies getan haben. Auf diese Weise kann das OP aus Ihrer Antwort lernen, anstatt sie nur zu kopieren / einzufügen.
Oldskool

1

path.extnamewird den Trick in den meisten Fällen tun. Es enthält jedoch alles nach dem letzten ., einschließlich der Abfragezeichenfolge und des Hash-Fragments einer http-Anforderung:

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

In solchen Fällen sollten Sie Folgendes ausprobieren:

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'

Beachten Sie, dass Erweiterungen mit mehreren Zeiträumen (z. B. .tar.gz) überhaupt nicht funktionieren path.extname.


0

Die folgende Funktion teilt die Zeichenfolge und gibt den Namen und die Erweiterung zurück, unabhängig davon, wie viele Punkte sich in der Erweiterung befinden. Es gibt eine leere Zeichenfolge für die Erweiterung zurück, wenn keine vorhanden ist. Namen, die mit Punkten und / oder Leerzeichen beginnen, funktionieren ebenfalls.

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

importiere extname, um die Erweiterung der Datei zurückzugeben:

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

Dabei ist Datei der Dateiname des Formulars


0

Sie können mit path.parse (Pfad) , zum Beispiel

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

0

Probier diese

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'));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.