2014-11-18 2 views
1

Попытка найти правильный путь для загрузки файла i.e. профиля пользователя и сохранения на сервере с использованием MeteorJS.Загрузка файла изображения в MeteorJS

Я попробовал CollectionFS несколько месяцев назад, он обновил веб-страницу браузера/Метеор до того, как файл был сохранен в файловой системе сервера, в результате чего была показана сломанная ссылка на изображение.

Я прочитал этот пост, но я не хочу использовать S3 и хочу, чтобы я избегал проблемы с неровной ссылкой. Может быть, мне нужен обратный вызов, чтобы сказать Метеор НЕ обновить веб-страницу, пока изображение не будет полностью написана (и размеры) на сервере: meteorjs image upload/conversion

+0

Что касается вашей проблемы с отображением неправильного изображения, вы можете написать URL-адрес изображения в коллекцию Meteor после завершения загрузки. Если изображение 'src' зависит от коллекции метеоров, изображение автоматически обновит его' src' после завершения загрузки –

+0

Это то, что делает CollectionFS, только он не проверял, был ли файл записан до обновления коллекция. –

ответ

1

Для маленьких файлов размером способ может быть, чтобы сохранить их в виде base64 строки внутри сама коллекция. Поиск очень быстрый.

Для чтения файла можно использовать перетаскивание или выберите файл, а затем нормальный JavaScript как

var reader = new FileReader(); 
         var filename = file.name; 

         reader.readAsDataURL(file); 
         reader.onload = function (imgsrc) { 
          var fileVar = imgsrc.target.result; 
          $("#FileUploadingAttachmentNewWay").val(fileVar); 
          $("#FileUploadingAttachmentNameNewWay").val(file.name); 

          $("#FileUploadingAttachmentNewWay").click(); 
         } 

Для чтения обратно вам нужно изменить, если из base64 и поставить его в временный элемент, который вы выберите и скачать (все в фоновом режиме). В метеор заметил, что если размер файла больше 4-5 мб, сбор может быть поврежден, поэтому у нас есть ограничение в размере изображения.

Код, приведенный ниже, предназначен для того, чтобы назначить base64 в a и загрузить его. Его некачественное качество и детали из учебников, но вы получите точку (ее из старого тестового проекта).

function download(strData, strFileName, strMimeType) { 
     var D = document, 
      A = arguments, 
      a = D.createElement("a"), 
      d = A[0], 
      n = A[1], 
      t = A[2] || "application/octet"; 
     //debugger; 
     //build download link: 
     a.href = strData.replace("data:;", "data:" + strMimeType + ";").replace("data:text/plain;", "data:" + strMimeType + ";"); 

     //trying to avoid chrome specific crash (works ok on firefox though) issue 69227 google chrome====> 
     //convert to binary in ArrayBuffer this needs change 
     var binStr1 = a.href.replace("data:application/octet;base64,", "") 
      .replace("data:image/png;base64,", "") 
      .replace("data:image/bmp;base64,", "") 
      .replace("data:image/jpeg;base64,", "") 
      .replace("data:application/msword;base64,", "") 
      .replace("data:application/vnd.ms-excel;base64,", "") 
      .replace("data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,", "") 
      .replace("data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,", ""); 

     var binStr = atob(binStr1); 

     var buf = new ArrayBuffer(binStr.length); 
     var view = new Uint8Array(buf); 
     for (var i = 0; i < view.length; i++) 
      view[i] = binStr.charCodeAt(i); 

     var blob = new Blob([view], { 'type': 'application/octet' }); 
     var URL = webkitURL.createObjectURL(blob) 

     a.href = URL; 
     //<================================================================================================= 

     if (window.MSBlobBuilder) { // IE10 
      var bb = new MSBlobBuilder(); 
      bb.append(strData); 
      return navigator.msSaveBlob(bb, strFileName); 
     } /* end if(window.MSBlobBuilder) */ 



     if ('download' in a) { //FF20, CH19 
      a.setAttribute("download", n); 
      a.innerHTML = "downloading..."; 
      D.body.appendChild(a); 
      setTimeout(function() { 
       try { 
        //a.id = "clickToDownload"; 
        //$("#clickToDownload").click(); 
        var e = D.createEvent("MouseEvents"); 
        e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 
        a.dispatchEvent(e); 
        D.body.removeChild(a); 
       } 
       catch (e) { 
        $.notify("There has been an error trying to download file, please try again or with another browser: " + e.message, "error"); 
       } 
      }, 66); 
      return true; 
     }; /* end if('download' in a) */ 



     //do iframe dataURL download: (older W3) 
     var f = D.createElement("iframe"); 
     D.body.appendChild(f); 
     f.src = "data:" + (A[2] ? A[2] : "application/octet-stream") + (window.btoa ? ";base64" : "") + "," + (window.btoa ? window.btoa : escape)(strData); 
     setTimeout(function() { 
      D.body.removeChild(f); 
     }, 333); 
     return true; 
    } 
+0

Вау, это действительно уродливый код. –

+0

Действительно, но с небольшой очисткой вы будете готовы. Основная идея заключается в том, что для небольших файлов вы можете разместить их в качестве базы строк в базе данных. не нужно пытаться находить сложные решения или добавлять и т. д. Изображение профиля очень мало, как 5-10кб и идеально подходит в качестве базовой строки 64. Вы можете использовать его как отдельную коллекцию или внутри вашей пользовательской коллекции. – user1855793