Node.js dostaje rozszerzenie pliku

209

Tworzę funkcję przesyłania plików w node.js z express 3.

Chciałbym pobrać rozszerzenie pliku obrazu. więc mogę zmienić nazwę pliku, a następnie dołączyć do niego rozszerzenie pliku.

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

Jak mogę uzyskać rozszerzenie obrazu w node.js?

georgesamper
źródło
1
stackoverflow.com/questions/10431845/… powtórzyć?
bill automata
3
Czy to nie pytanie o typy MIME, chcę rozszerzenie pliku
georgesamper

Odpowiedzi:

472

Uważam, że możesz wykonać następujące czynności, aby uzyskać rozszerzenie nazwy pliku.

var path = require('path')

path.extname('index.html')
// returns
'.html'
Snowfish
źródło
54
Bądź ostrożny, pobierze on znaki tylko po ostatniej kropce, więc nazwy plików app.css.gzwrócą tylko .gzi nie .css.gz, co może lub nie być tym, czego chcesz.
xentek
18
W takim przypadku wystarczy użyćfilename.split('.').pop();
Aamir Afridi
12
@AamirAfridi Zwraca ten sam ciąg tylko bez ..
niezdefiniowany
13
Postaraj 'filename.css.gz'.split('.').slice(1).join('.')się uzyskać wszystkie rozszerzenia
Trevor
10
Ogólnie rozszerzenie jest ostatnie. A gdy oczekujemy więcej niż jednego, na przykład tar.gz. lepiej sprawdzić, czy istnieje na końcu, czy nie. na przykład używając wyrażenia regularnego. „tar.gz $” lub budując funkcję, która to robi. jak sprawdzanie tego od końca i powrót i sprawdzenie, czy pasuje całkowicie. i będziesz miał tę funkcję, która sprawdza rozszerzenie. CZEMU? bo co z plikami takimi jak jone.lastTest.654654556.tar.gz tutaj, oczekiwanym rozszerzeniem jest tar.gz, ale jeśli zastosujesz dowolną funkcję, która daje formę 1. kropki, to nie będzie działać, jak widać
Mohamed Allal
33

Aktualizacja

Ponieważ oryginalna odpowiedź, extname () została dodana do pathmodułu, patrz odpowiedź Snowfish

Oryginalna odpowiedź:

Korzystam z tej funkcji, aby uzyskać rozszerzenie pliku, ponieważ nie znalazłem sposobu na zrobienie tego w łatwiejszy sposób (ale myślę, że jest):

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

aby go użyć, musisz wymagać „ścieżki”.

inna metoda, która nie korzysta z modułu ścieżki:

function getExtension(filename) {
    var i = filename.lastIndexOf('.');
    return (i < 0) ? '' : filename.substr(i);
}
dievardump
źródło
4
Tak, to działa. Pomyślałem, że łatwiej byłoby użyć węzła. Oto, co zrobiłem:var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
georgesamper
6
Naprawdę powinieneś po prostu użyć modułu ścieżki, jak wskazała odpowiedź @ Snowfish, a nie pisać własnego. Więcej informacji: nodejs.org/api/path.html#path_path_extname_p
xentek
a co jeśli pliki nie pokazują rozszerzeń?
oldboy
19
// you can send full url here
function getExtension(filename) {
    return filename.split('.').pop();
}

Jeśli używasz ekspresowego, dodaj następujący wiersz podczas konfigurowania oprogramowania pośredniego (bodyParser)

app.use(express.bodyParser({ keepExtensions: true}));
Kamrul
źródło
12

O wiele bardziej wydajne jest użycie tej substr()metody zamiast split()&pop()

Spójrz na różnice w wydajności tutaj: http://jsperf.com/remove-first-character-from-string

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

wprowadź opis zdjęcia tutaj

Aktualizacja sierpień 2019 r. Jak wskazał @xentek w komentarzach; substr()jest teraz uważany za funkcję starszą ( dokumentacja MDN ). Zamiast tego możesz użyć substring(). Różnica między substr()i substring()polega na tym, że drugi argument substr()to maksymalna długość do zwrócenia, podczas gdy drugi argument substring()to indeks, na którym należy się zatrzymać (bez uwzględnienia tego znaku). Również substr()akceptuje negatywne pozycje zaczynają być wykorzystywane jako przesunięcie od końca łańcucha natomiast substring()nie.

magikMaker
źródło
Pojawiło się ostrzeżenie, substrponieważ jest uważane za starszą funkcję i należy jej unikać, gdy jest to możliwe - Więcej informacji na temat MDN
Core972
Podczas wykonywania testu substr (1) należy również wziąć pod uwagę czas spędzony na path.extname
eugenekr
11

To rozwiązanie obsługuje kwerendy!

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'
aleclarson
źródło
6

Proste rozwiązanie bez potrzeby, które rozwiązuje problem przedłużenia okresu:

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

Lub jeśli nie chcesz początkowej kropki:

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

Sprawdź, czy plik ma również rozszerzenie.

Smileham
źródło
4

Myślę, że mapowanie nagłówka Content-Type w żądaniu również będzie działać. Działa to nawet w przypadku przesyłania pliku bez rozszerzenia. (gdy nazwa pliku nie ma rozszerzenia w żądaniu)

Załóżmy, że wysyłasz dane za pomocą 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--

Tutaj nazwa Nagłówek Content-Type zawiera typ MIME danych. Mapowanie tego typu MIME na rozszerzenie da ci rozszerzenie pliku :).

Restify BodyParser konwertuje ten nagłówek na właściwość o typie nazwy

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

Możesz użyć tego nagłówka i ręcznie wykonać mapowanie rozszerzeń (podłańcuch itp.), Ale istnieją też gotowe biblioteki. Poniżej dwa były najlepsze wyniki, gdy wyszukiwałem w Google

  • mim
  • typy MIME

a ich użycie jest również proste:

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

powyżej fragmentu wypisze png na konsolę.

rozaydin
źródło
2
var fileName = req.files.upload.name;

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

var extension = arr[length-1];
rajesh
źródło
1
skąd pochodzi zmienna długości?
Angel S. Moreno,
3
Dodaj wyjaśnienie do swojej odpowiedzi. W ten sposób PO może faktycznie zrozumieć, co zrobiłeś i dlaczego to zrobiłeś. W ten sposób OP może uczyć się na podstawie odpowiedzi, a nie tylko ją kopiować / wklejać.
Oldskool,
1

path.extnamezrobi lewę w większości przypadków. Będzie jednak zawierał wszystko po ostatnim ., w tym ciąg zapytania i fragment skrótu żądania http:

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

W takich przypadkach możesz spróbować czegoś takiego:

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'

Pamiętaj, że rozszerzenia z wieloma kropkami (np. .tar.gz) W ogóle nie będą działać path.extname.

dójka
źródło
0

Poniższa funkcja dzieli ciąg i zwraca nazwę i rozszerzenie bez względu na liczbę kropek w rozszerzeniu. Zwraca pusty ciąg dla rozszerzenia, jeśli go nie ma. Nazwy zaczynające się od kropek i / lub białych znaków działają również.

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')
Vidar
źródło
0

import extname, aby zwrócić rozszerzenie plik:

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

gdzie plik to „nazwa” formy

Vitalves
źródło
0

Możesz na przykład użyć path.parse (ścieżka)

const path = require('path');
const { ext } = path.parse('/home/user/dir/file.txt');
ns16
źródło
0

Spróbuj tego

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'));
tunnckoCore
źródło