수색…


비고

CollectionFS 패키지는 제작자에 의해 보관되지 않고 중단되었습니다. 그러나 Mongo의 GridFS 기능을 사용하기 위해 Atmosphere 나 Meteor 생태계에 대안 패키지가 없기 때문에 코드는 여전히 완벽하게 작동합니다. StackOverflow 문서에서 다른 GridFS 솔루션을 대체품으로 문서화 할 수있을 때까지 예제를 제거하지 않는 것이 좋습니다.

추가 연구
Filepicker.io 업로드 및 이미지 변환
다리오의 파일 패턴 저장
Micha Roon의 파일 업로드 패턴
EventedMind 파일 업로드 패키지

서버 / 클라이언트

파일 업로드는 원하는 작업에 따라 쉽거나 복잡 할 수 있습니다. 일반적으로 파일 자체를 전송하는 것이 그렇게 어렵지는 않습니다. 그러나 첨부 파일, 바이너리 파일 등의 주변에는 많은 경우가 있습니다. 실제로 가장 중요한 점은 수평 확장이며 서버를 두 번째, 세 번째 및 네 번째로 복제 할 때 작동하는 솔루션을 만드는 것입니다.

기본적인 서버 / 클라이언트 업로드 모델부터 시작해 보겠습니다. 우리는 파일 입력 요소를 문서 객체 모델에 추가하는 것으로 시작합니다.

<template name="example">
  <input type=file />
</template>

그런 다음 컨트롤러 내의 입력 요소에 이벤트를 첨부하고 로컬 Meteor 메소드 인``startFileTransfer ''를 호출하여 전송을 시작하십시오.

// client/example.js
Template.example.events({
  'change input': function(ev) {  
    _.each(ev.srcElement.files, function(file) {
      Meteor.startFileTransfer(file, file.name);
    });
  }
});

// client/save.js
/**
 * @blob (https://developer.mozilla.org/en-US/docs/DOM/Blob)
 * @name the file's name
 * @type the file's type: binary, text (https://developer.mozilla.org/en-US/docs/DOM/FileReader#Methods) 
 *
 * TODO Support other encodings: https://developer.mozilla.org/en-US/docs/DOM/FileReader#Methods
 * ArrayBuffer / DataURL (base64)
 */
Meteor.startFileTransfer = function(blob, name, path, type, callback) {
  var fileReader = new FileReader(),
    method, encoding = 'binary', type = type || 'binary';
  switch (type) {
    case 'text':
      // TODO Is this needed? If we're uploading content from file, yes, but if it's from an input/textarea I think not...
      method = 'readAsText';
      encoding = 'utf8';
      break;
    case 'binary': 
      method = 'readAsBinaryString';
      encoding = 'binary';
      break;
    default:
      method = 'readAsBinaryString';
      encoding = 'binary';
      break;
  }
  fileReader.onload = function(file) {
    Meteor.call('saveFileToDisk', file.srcElement.result, name, path, encoding, callback);
  }
  fileReader[method](blob);
}

클라이언트는 saveFileToDisk 서버 메소드를 호출합니다.이 메소드는 실제 전송을 수행하고 모든 것을 디스크에 저장합니다.

// 
/**
 * TODO support other encodings:
 * http://stackoverflow.com/questions/7329128/how-to-write-binary-data-to-a-file-using-node-js
 */
Meteor.methods({
  saveFileToDisk: function(blob, name, path, encoding) {
    var path = cleanPath(path), fs = __meteor_bootstrap__.require('fs'),
      name = cleanName(name || 'file'), encoding = encoding || 'binary',
      chroot = Meteor.chroot || 'public';
    // Clean up the path. Remove any initial and final '/' -we prefix them-,
    // any sort of attempt to go to the parent directory '..' and any empty directories in
    // between '/////' - which may happen after removing '..'
    path = chroot + (path ? '/' + path + '/' : '/');

    // TODO Add file existance checks, etc...
    fs.writeFile(path + name, blob, encoding, function(err) {
      if (err) {
        throw (new Meteor.Error(500, 'Failed to save file.', err));
      } else {
        console.log('The file ' + name + ' (' + encoding + ') was saved to ' + path);
      }
    }); 

    function cleanPath(str) {
      if (str) {
        return str.replace(/\.\./g,'').replace(/\/+/g,'').
          replace(/^\/+/,'').replace(/\/+$/,'');
      }
    }
    function cleanName(str) {
      return str.replace(/\.\./g,'').replace(/\//g,'');
    }
  }
});

그것은 일종의 맨손으로 접근하는 방식이며, 원하는 바가 많습니다. CSV 파일 등을 업로드하는 것이 좋겠지 만 그게 전부입니다.

Dropzone (철제 : 라우터 포함)

Dropzone UI와 REST 엔드 포인트가 통합 된 좀 더 세련된 인터페이스를 원한다면 UI 헬퍼를 사용하여 사용자 정의 REST 경로와 패키지를 추가해야 할 것입니다.

Iron Router 및 Dropzone을 가져 오기 시작하십시오.

 meteor add iron:router
 meteor add awatson1978:dropzone

그리고 dropzone 도우미에 지정된 업로드 URL 경로를 구성하십시오.

Router.map(function () {
    this.route('uploads', {
      where: 'server',
      action: function () {
        var fs = Npm.require('fs');
        var path = Npm.require('path');
        var self = this;

        ROOT_APP_PATH = fs.realpathSync('.');

        // dropzone.js stores the uploaded file in the /tmp directory, which we access
        fs.readFile(self.request.files.file.path, function (err, data) {

          // and then write the file to the uploads directory
          fs.writeFile(ROOT_APP_PATH + "/assets/app/uploads/" +self.request.files.file.name, data, 'binary', function (error, result) {
            if(error){
              console.error(error);
            }
            if(result){
              console.log('Success! ', result);
            }
          });
        });
      }
    });
  });

시원한! Snazzy UI와 프로그래밍 가능한 REST 엔드 포인트를 갖춘 파일 업 로더가 있습니다. 불행히도 이것은 특히 잘 확장되지 않습니다.

Filepicker.io

규모를 확장하려면 서버에서 로컬 저장소 사용을 중단하고 전용 파일 저장소 서비스를 사용하거나 수평 저장소 계층을 구현해야합니다. 확장 가능한 파일 저장소를 시작하는 가장 쉬운 방법은 S3, Azure, Rackspace 및 Dropbox를 지원하는 Filepicker.io와 같은 솔루션을 사용하는 것입니다. 로드 피커는 잠시 동안 인기있는 Filerpicker 패키지가되었습니다.

meteor add mrt:filepicker

Filepicker 패턴은 제 3 자 통합과 관련하여 다른 솔루션과 약간 다릅니다. Filepicker 입력을 추가하여 시작하십시오.이 입력은 Meteor 앱에서 매우 드문 패턴 인 data- * 속성에 크게 의존합니다.

<input type="filepicker"
  id="filepickerAttachment"
  data-fp-button-class="btn filepickerAttachment"
  data-fp-button-text="Add image" 
  data-fp-mimetypes="image/*"
  data-fp-container="modal"
  data-fp-maxsize="5000000" 
  data-fp-services="COMPUTER,IMAGE_SEARCH,URL,DROPBOX,GITHUB,GOOGLE_DRIVE,GMAIL">

API 키를 설정하고, 파일 피기 위젯을 만들고, 트리거하고, 출력을 관찰하고 싶습니다.

if(Meteor.isClient){
  Meteor.startup(function() {
    filepicker.setKey("YourFilepickerApiKey");
  });
  Template.yourTemplate.rendered = function(){
    filepicker.constructWidget($("#filepickerAttachment"));
  }
  Template.yourTemplate.events({
  'change #filepickerAttachment': function (evt) {
    console.log("Event: ", evt, evt.fpfile, "Generated image url:", evt.fpfile.url);
  });
});

CollectionFS

그러나 스토리지에 대해 진지하게 생각하고 수백만 개의 이미지를 저장하려면 Mongo의 GridFS 인프라를 활용하고 자신에게 스토리지 계층을 만들어야합니다. 이를 위해서는 뛰어난 CollectionFS 하위 시스템이 필요합니다.

필요한 패키지를 추가하여 시작하십시오.

meteor add cfs:standard-packages
meteor add cfs:filesystem

그리고 파일 업로드 요소를 개체 모델에 추가합니다.

<template name="yourTemplate">
    <input class="your-upload-class" type="file">
</template>

그런 다음, 클라이언트에 이벤트 컨트롤러를 추가하십시오.

Template.yourTemplate.events({
    'change .your-upload-class': function(event, template) {
        FS.Utility.eachFile(event, function(file) {
            var yourFile = new FS.File(file);
            yourFile.creatorId = Meteor.userId(); // add custom data
            YourFileCollection.insert(yourFile, function (err, fileObj) {
                if (!err) {
                   // do callback stuff
                }
            });
        });
    }
});

그리고 서버에 컬렉션을 정의하십시오.

YourFileCollection = new FS.Collection("yourFileCollection", {
    stores: [new FS.Store.FileSystem("yourFileCollection", {path: "~/meteor_uploads"})]
});
YourFileCollection.allow({
    insert: function (userId, doc) {
        return !!userId;
    },
    update: function (userId, doc) {
        return doc.creatorId == userId
    },
    download: function (userId, doc) {
        return doc.creatorId == userId
    }
});

Raz 덕분에이 훌륭한 예가되었습니다. 모든 CollectionFS에서 수행 할 수있는 작업에 대한 자세한 내용은 전체 CollectionFS 문서를 확인하십시오.

서버 업로드

다음 스크립트는 서버 파일 시스템에서 서버로 파일을 업로드하기위한 것입니다. 주로 설정 파일과 파일 워처에 사용됩니다.

//https://forums.meteor.com/t/read-file-from-the-public-folder/4910/5

// Asynchronous Method.
Meteor.startup(function () {
    console.log('starting up');

    var fs = Npm.require('fs');
    // file originally saved as public/data/taxa.csv
    fs.readFile(process.cwd() + '/../web.browser/app/data/taxa.csv', 'utf8', function (err, data) {
        if (err) {
            console.log('Error: ' + err);
            return;
        }

        data = JSON.parse(data);
        console.log(data);
    });
});


// Synchronous Method.
Meteor.startup(function () {
    var fs = Npm.require('fs');
    // file originally saved as public/data/taxa.csv
    var data = fs.readFileSync(process.cwd() + '/../web.browser/app/data/taxa.csv', 'utf8');

    if (Icd10.find().count() === 0) {
        Icd10.insert({
            date:  new Date(),
            data:  JSON.parse(data)
        });
    }
});


Meteor.methods({
  parseCsvFile:function (){
    console.log('parseCsvFile');

    var fs = Npm.require('fs');
    // file originally saved as public/data/taxa.csv
    var data = fs.readFileSync(process.cwd() + '/../web.browser/app/data/taxa.csv', 'utf8');
    console.log('data', data);
  }
});


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow