在MeteorJS中上传图像文件

时间:2014-11-18 22:06:15

标签: javascript meteor

尝试使用MeteorJS找到上传文件的正确方式,即用户个人资料照片,并保存到服务器。

几个月前我尝试过CollectionFS,它在将文件保存到服务器的文件系统之前刷新了浏览器/ Meteor网页,最终显示了一个损坏的图像链接。

我读过这篇文章,但我不想使用S3,并希望确保避免链接问题。也许我需要一个回调告诉Meteor NOT刷新网页,直到图像在服务器上完全写入(并调整大小): meteorjs image upload / conversion

1 个答案:

答案 0 :(得分: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更改,并将其放在您单击并下载的临时元素中(全部在后台)。在meteor中注意到,如果文件大小超过4-5mb,则集合可能会被破坏,因此我们对图像大小有限制。

以下代码是您分配base64并下载它。它不是很好的质量和部分来自教程,但你会得到重点(它来自一个旧的测试项目)。

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