文件上傳之漸進式加強

1、前言
隨着HTML5規範的提出,咱們又多了一種上傳方式的選擇。相對企業信息系統而言,互聯網產品的用戶羣體要普遍不少,不一樣的用戶羣體一般會選擇不一樣的瀏覽器,不一樣的瀏覽器對HTML5規範的支持程度不一樣。單一的上傳方式根本沒法知足全部用戶。咱們須要採用 漸進式加強的上傳方式爲用戶提供較好的上傳體驗。
 
2、案例分析
咱們以QQ相冊做爲案例,分析漸進式加強的上傳方式。
先看一下QQ相冊的圖片預覽功能:

 
是否是很炫?以上界面是用Flash實現的,如今我禁用Flash:
 
 
再看看QQ相冊,先提示我安裝瀏覽器插件:
 
我選擇不安裝,界面就變成這樣:
 
咱們看到了醜陋的input type='file'了。底部能夠看到提示語:請安裝Flash或使用極速上傳。
我選擇極速上傳並安裝瀏覽器插件,再啓用Flash插件,從新進入相冊上傳界面:
 
界面是否是更炫了?連本地磁盤的圖片都被讀取了。瀏覽器插件是否是很可怕?
 
由此,咱們能夠看出QQ相冊的圖片上傳功能,漸進式加強的優先級是這樣的:
瀏覽器插件 -> Flash -> 普通上傳
整個過程壓根兒沒考慮HTML5的解決方案。也許跟QQ相冊的用戶羣體有關。
 
3、139郵箱文件上傳漸進式加強
經過對業界其它產品的分析再結合咱們本身產品的用戶特徵,139郵箱文件上傳漸進式加強的優先級是這樣的:
瀏覽器插件 -> HTML5 -> Flash -> 普通上傳
 
什麼?爲何139郵箱的上傳方式HTML5優先於Flash?緣由以下:
(1)、HTML5是瀏覽器原生提供的能力,默認狀況下沒法被禁用,並且不須要另外加載文件,可減小http請求。
(2)、有些瀏覽器會默認禁用Flash插件,好比FireFox25默認狀況下就是禁用Flash的,須要單擊地址欄左側的紅色圖標才能啓用Flash插件:
 
(3)、第三個緣由也是最重要的緣由,公司某些領導偏心FireFox瀏覽器又不知道怎麼啓用Flash插件。領導的愛好決定了產品的走向,是否是很蛋疼?若是大家公司的領導偏心其它瀏覽器,請自行調整優先級。
 
4、能力檢測
肯定漸進式加強的優先級以後,接下來就須要對用戶的瀏覽器作能力檢測:是否安裝自定義的瀏覽器插件、是否支持HTML5上傳、是否安裝Flash插件。
判斷是否安裝自定義的瀏覽器插件,完整代碼以下:
function isUploadControlSetup() {
    var setup = false;

    if (window.ActiveXObject) {//ie
        try {
            if (new ActiveXObject("Cxdndctrl.Upload")) {
                setup = true;
            }
        } catch (ex) {
            try {
                if (new ActiveXObject("ExCxdndCtrl.ExUpload")) {
                    setup = true;
                }
            } catch (e) {
                console.log(ex);
                console.log('建立ActiveXObject("Cxdndctrl.Upload")及ActiveXObject("ExCxdndCtrl.ExUpload")對象失敗!');
            }
        }
    } else if (navigator.plugins) {//firefox chrome
        var mimetype = navigator.mimeTypes["application/x-richinfo-cxdnd3"];

        setup = (mimetype && mimetype.enabledPlugin) ? true : false;
    }

    return setup;
}
粗體字部分須要替換成建立本身的瀏覽器插件實例對象所需的字符串參數。如139郵箱小工具參數值爲: Cxdndctrl.Upload
 
判斷是否支持HTML5的上傳方式,完整代碼以下:
function isSupportHtml5Upload() {
    if (window.File && window.FileList && window.FileReader && window.Blob && window.FormData && window.Worker && "withCredentials" in (new XMLHttpRequest)) {
        return true;
    }
    return false;
}
 
判斷是否安裝Flash插件,IE瀏覽器須要經過try{}catch(){}試探建立ActiveXObject實例,標準瀏覽器可迭代navigator.plugins,完整的代碼以下:
function getVersionInIE() {
    var version = 0;
    var axo;

    // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
    try {
        // version will be set for 7.X or greater players
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
        version = axo.GetVariable("$version");
    } catch (e) {
    }

    if (!version) {
        try {
            // version will be set for 6.X players only
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");

            // installed player is some revision of 6.0
            // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
            // so we have to be careful.

            // default to the first public version
            version = "WIN 6,0,21,0";

            // throws if AllowScripAccess does not exist (introduced in 6.0r47)
            axo.AllowScriptAccess = "always";

            // safe to call for 6.0r47 or greater
            version = axo.GetVariable("$version");

        } catch (e) {
        }
    }

    if (!version) {
        try {
            // version will be set for 4.X or 5.X player
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
            version = axo.GetVariable("$version");
        } catch (e) {
        }
    }

    if (!version) {
        try {
            // version will be set for 3.X player
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
            version = "WIN 3,0,18,0";
        } catch (e) {
        }
    }

    if (!version) {
        try {
            // version will be set for 2.X player
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
            version = "WIN 2,0,0,11";
        } catch (e) {
        }
    }

    if (version !== 0) {
        var match = version.match(/(\d+),(\d+).*$/);

        if (match[0]) {
            version = Number(match[1] + "." + match[2]);
        } else {
            version = 0;
        }
    }

    return version;
}

function getVersionInOthers() {
    var v = 0;
    if (navigator.plugins && navigator.plugins.length > 0 && navigator.plugins["Shockwave Flash"]) {
        var plugins = navigator.plugins["Shockwave Flash"];
        for (var i = 0; i < plugins.length; i++) {
            var swf = plugins[i];
            if (swf.enabledPlugin && (swf.suffixes.indexOf("swf") != -1) && navigator.mimeTypes["application/x-shockwave-flash"]) {
                var match = plugins.description.match(/ (\d+(?:\.\d+)?)/);
                if (match) {
                    var v = parseInt(match[1]);
                    break;
                }
            }
        }
    }
    return v;
}
 
 
5、HTML5上傳方式分析
斷點續傳,秒傳都是創建在文件分塊的基礎之上的,分塊上傳須要讀取文件塊的內容,並計算文件內容的MD5值,讀取文件內容須要用到FileReader,而計算MD5值須要用到Worker 
 
爲何咱們須要使用Worker來計算MD5值?
由於計算MD5值須要消耗較多的CPU時間,瀏覽器自己是採用單線程模式工做的,爲了不MD5值的計算阻塞其它JS代碼的執行,咱們須要使用Worker對象建立新線程完成MD5值的計算。
 
6、 什麼?你是IE6用戶並且還有潔癖不想安裝任何瀏覽器插件,下圖紅圈按鈕就是爲你量身定製的,歡樂的戳它吧
相關文章
相關標籤/搜索