溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

FireFox瀏覽器如何使用Javascript上傳大文件

發(fā)布時間:2021-10-08 16:39:20 來源:億速云 閱讀:121 作者:iii 欄目:開發(fā)技術

本篇內容主要講解“FireFox瀏覽器如何使用Javascript上傳大文件”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“FireFox瀏覽器如何使用Javascript上傳大文件”吧!

本程序是利用3.x的Firefox瀏覽器可以讀取本地文件的特性,實現通過xmlHttPRequest上傳大文件功能,并在可以上傳過程中動態(tài)顯示上傳進度。略加修改,并與服務器端配合,可以實現斷點續(xù)傳等諸多功能。
本例主要是研究FireFox的file-input節(jié)點的一些特性,其他客戶端應用,如Flash、Sliverlight等,在實現客戶端大文件上傳時,在數據傳輸與服務器端存儲等方面,與本例的思路基本一致。
注意:文件體積似乎有臨界點,但這個臨界點是多少尚未確認。建議不要用此方法上傳超過100M的文件。
以下是客戶端javascript代碼

復制代碼 代碼如下:

/*
 * FireFoxFileSender version 0.0.0.1
 * by MK winnie_mk(a)126.com
 *
 * 【本程序僅限于FireFox3.x版本,其他瀏覽器是否可以運行未做測試?!?br/> * 【測試通過:FireFox 3.6.8 / Apache/2.2.11 (Win32) php/5.2.6 】
 * ******************************************************************************
 * 本程序是利用3.x的FireFox瀏覽器可以讀取本地文件的特性
 * 實現通過xmlhttpRequest上傳大文件功能
 * 并在可以上傳過程中動態(tài)顯示上傳進度
 * 略加修改,并與服務器端配合,可以實現斷點續(xù)傳等諸多功能
 * 本例主要是研究FireFox的file-input節(jié)點的一些特性
 * 其他客戶端應用,如Flash、Sliverlight等,在實現客戶端大文件上傳時
 * 在數據傳輸與服務器端存儲等方面,與本例的思路基本一致
 * 注意:文件體積似乎有個臨界點,但這個臨界點是多少尚未確認。建議不要用此方法上傳超過100M的文件。
 * ******************************************************************************
 */
function FireFoxFileSender(config){
    var conf = config || {};
    /*
     * 錯誤信息隊列
     */
    this.errMsg = [];   
    /*
     * 判斷各參數是否齊備
     */
    this.f = typeof conf.file == 'string' ?
     document.getElementById(conf.file) : conf.file;
    if(!this.f){ this.errMsg.push('Error: Not set the input file.'); }
    else if(this.f.files.length < 1){ this.errMsg.push('Error: Not select a file.'); }
    else {
        this.fileName = this.f.value;
        /*
         * 在嘗試直接發(fā)送二進制流時失敗,改用發(fā)送base64編碼數據。
         */
        this.data = (this.data = this.f.files[0].getAsDataURL())
      .substr(this.data.indexOf(',') + 1);
        this.length = this.data.length;
        /*
         * 文件實際大小
         */
        this.fileSize = this.f.files[0].fileSize;
        /*
         * 文件類型
         */
        this.contentType = this.f.files[0].fileType;
    }
    /*
     * 服務器端接收地址
     */
    this.url = conf.url;
    if(!this.url){
     this.errMsg.push('Error: Not set the instance url to send binary.');
  }
    /*
     * 發(fā)送數據包的大小。默認100kb
     */
    this.packageSize = conf.packageSize || 102400;
    /*
     * 每次發(fā)送數據包大小應為4的倍數,確保服務器端轉換base64編碼正確。
     */
    if(this.packageSize % 4 != 0)
     this.packageSize = parseInt(this.packageSize / 4) * 4;

    this.onSendFinished = conf.onSendFinished || null;
    this.onSending = conf.onSending || null;
    this.onError = conf.onError || null;
}
FireFoxFileSender.prototype = {
    /*
     * 記錄當前發(fā)送的數據
     */
    currentData : null,
    /*
     * 記錄讀取位置
     */
    position : 0,
    /*
     * 數據大小。該值為base64字符串的長度。
     */
    length : -1,
    /*
     * 檢查錯誤隊列,嘗試觸發(fā)onError事件
     */
    checkError : function(){
        if(this.errMsg.length > 0){
            /*
             * 觸發(fā)onError事件
             */
            typeof this.onError == 'function' && this.onError(this.errMsg);
            return;
        }
    },
    /*
     * 創(chuàng)建XMLHttpRequest
     */
    createSender : function(){
        var xhr = new XMLHttpRequest();
        xhr.open('POST', this.url, true);
        var _ = this;
        xhr.onreadystatechange = function(){
            /*
             * 當服務器段響應正常,則循環(huán)讀取發(fā)送。
             */
            if(xhr.readyState == 4 && xhr.status == 200){
                /*
                 * 觸發(fā)onSending事件
                 */
                if(typeof _.onSending == 'function') _.onSending(_, xhr);
                /*
                 * 延時發(fā)送下一次請求,否則服務器負擔過重
                 */
                var send = setTimeout(function(){
                    _.send();
                    clearTimeout(send);
                    send = null;
                }, 100);               
            }
        }
        return xhr;
    },
    /*
     * 發(fā)送數據
     */
    send : function(){
        this.checkError();
        /*
         * 獲取當前要發(fā)送的數據
         */
        this.currentData = this.data.substr(this.position, this.packageSize);
        /*
         * 更改postion,模擬數據流移位
         */
        this.position += this.currentData.length;
        /*
         * 如果讀取字符串長度大于0,則發(fā)送該數據
         * 否則觸發(fā)onSendFinished事件
         */
        if(this.currentData.length > 0) {
            var xhr = this.createSender();
            /*
             * 自定義頭部信息,通知服務器端文件相關信息
             * 實際應用時可修改此部分。
             */
            xhr.setRequestHeader('#FILE_NAME#', this.fileName);
            xhr.setRequestHeader('#FILE_SIZE#', this.length);
            xhr.setRequestHeader('#CONTENT_TYPE#', this.contentType);

            xhr.send(this.currentData);
        } else if(typeof this.onSendFinished == 'function') {
            /*
             * 觸發(fā)onSendFinished事件
             */
            this.onSendFinished(this);
        }
    },
    /*
     * 計算已發(fā)送數據百分比
     */
    percent : function(){
        if(this.length <= 0 ) return -1;
        return Math.round((this.position / this.length) * 10000) / 100;
    },
    onSendFinished : null,    //該事件是以本地數據發(fā)送完成為觸發(fā),并不是服務器端返回的完成信息。
    onSending : null,
    onError : null
}

/*
 * 上傳按鈕事件
 */
function send(fileID){
    var sender = new FireFoxFileSender(
        /*
         * 上傳配置文件
         */
        {
            /*
             * input file 元素,可以是dom節(jié)點,也可以是id的字符串值
             */
            file : fileID,
            /*
             * 接收上傳數據的服務器端地址
             */
            url : 'UPLOADER.php',
            /*
             * 每次發(fā)送數據包的大小??筛鶕掌骶唧w情況更改。IIS6默認為200K
             */
            packageSize : '200000',
            /*
             * 出現錯誤時觸發(fā)該事件。本例僅在初始化時判斷各參數是否齊備,并沒有拋出發(fā)送過程中的錯誤。
             */
            onError : function(arrMsg){
                alert(arrMsg.join('\r\n'));
                sender = null;
                delete sender;
            },
            /*
             * 發(fā)送過程中觸發(fā)該事件。本例中主要用于顯示進度。
             */
            onSending : function(sd, xhr){
                var per = sd.percent();
                document.getElementById('Message').innerHTML = per + '% ';
                /*
                 * 該判斷是在最后一次發(fā)送結束后,通過xhr的onreadystatechange事件觸發(fā)的
                 * 如果傳輸過程中沒有其他錯誤,基本可以確定為服務器端接收完成
                 */
                if(parseInt(per) == 100){ alert('服務器端接收完成'); }
            },
            /*
             * 該事件僅僅為【本地數據發(fā)送完成】時觸發(fā)。
             * 請區(qū)別本地數據發(fā)送完成和服務器端返回完成信息這兩種情況
             * 本例中并沒有對服務器接收信息的情況做響應
             * 即使服務器端沒有接收和保存任何數據
             * 只要確保xhr返回readyState == 4 和 status == 200
             * 發(fā)送就會繼續(xù)進行
             * 服務器端如何返回完成信息可以通過更改接收數據頁面的代碼自定實現
             * 然后通過對xhr.responseText的值來做判斷
             */
            onSendFinished : function(){
                alert('本地數據發(fā)送完成');
            }
        }
    );
    sender.send();
}

以下是服務器端php代碼

復制代碼 代碼如下:


/*
 * 獲取輸入信息
 */
$b64 = file_get_contents("php://input");
/*
 * 獲取頭部信息
 */
$headers = getallheaders();
$fileName = $headers['#FILE_NAME#'];
$contentType = $headers['#CONTENT_TYPE#'];

/*
 * 做一些判斷和處理...
 */

/*
 * 以下是服務器端對發(fā)送數據的簡單響應
 * - 假如有數據被post過來 則輸出對base64轉換為二進制流后,二進制流的長度
 * - 否則輸出0
 * 這僅僅是一個例子,并且在js端沒有接收這個信息
 * 同樣,也可以采用在header中寫入反饋信息等等方法
 * 回饋信息給客戶端
 * 主要目的是確定上傳過程中是否有其他問題出現
 * 以確保上傳文件完整
 */
if(!empty($b64)){
    $stream = base64_decode($b64);
    echo strlen($stream);
    /*
     * 追加方式寫入文件
     * 在此修改文件保存位置
     */
    $file = fopen('' . $fileName , 'a');
    if($file)
        if(fwrite($file, $stream))
            fclose($file);
} else echo '0';

客戶端完整代碼

復制代碼 代碼如下:


<!DOCTYPE HTML>
  2  <html>
  3  <head>
  4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5  <title>FireFoxFileSender - !! ONLY FOR FireFox !!</title>
  6  </head>
  7
  8  <body>
  9  <script type="text/Javascript">
 10  /*
 11  * FireFoxFileSender version 0.0.0.1
 12  * by MK winnie_mk(a)126.com
 13  *
 14  * 【本程序僅限于FireFox3.x版本,其他瀏覽器是否可以運行未做測試?!?br/> 15  * 【測試通過:FireFox 3.6.8 / Apache/2.2.11 (Win32) PHP/5.2.6 】
 16  * *********************************************************************************
 17  * 本程序是利用3.x的FireFox瀏覽器可以讀取本地文件的特性
 18  * 實現通過XMLHttpRequest上傳大文件功能
 19  * 并在可以上傳過程中動態(tài)顯示上傳進度
 20  * 略加修改,并與服務器端配合,可以實現斷點續(xù)傳等諸多功能
 21  * 本例主要是研究FireFox的file-input節(jié)點的一些特性
 22  * 其他客戶端應用,如Flash、Sliverlight等,在實現客戶端大文件上傳時
 23  * 在數據傳輸與服務器端存儲等方面,與本例的思路基本一致
 24  * 注意:文件體積似乎有個臨界點,但這個臨界點是多少尚未確認。建議不要用此方法上傳超過100M的文件。
 25  * *********************************************************************************
 26  */
 27  function FireFoxFileSender(config){
 28     var conf = config || {};
 29     /*
 30      * 錯誤信息隊列
 31      */
 32     this.errMsg = [];   
 33     /*
 34      * 判斷各參數是否齊備
 35      */
 36     this.f = typeof conf.file == 'string' ? document.getElementById(conf.file) : conf.file;
 37     if(!this.f){ this.errMsg.push('Error: Not set the input file.'); }
 38     else if(this.f.files.length < 1){ this.errMsg.push('Error: Not select a file.'); }
 39     else {
 40         this.fileName = this.f.value;
 41         /*
 42          * 在嘗試直接發(fā)送二進制流時失敗,改用發(fā)送base64編碼數據。
 43          */
 44         this.data = (this.data = this.f.files[0].getAsDataURL()).substr(this.data.indexOf(',') + 1);
 45         this.length = this.data.length;
 46         /*
 47          * 文件實際大小
 48          */
 49         this.fileSize = this.f.files[0].fileSize;
 50         /*
 51          * 文件類型
 52          */
 53         this.contentType = this.f.files[0].fileType;
 54     }
 55     /*
 56      * 服務器端接收地址
 57      */
 58     this.url = conf.url;
 59     if(!this.url){ this.errMsg.push('Error: Not set the instance url to send binary.'); }
 60     /*
 61      * 發(fā)送數據包的大小。默認100kb
 62      */
 63     this.packageSize = conf.packageSize || 102400;
 64     /*
 65      * 每次發(fā)送數據包大小應為4的倍數,確保服務器端轉換base64編碼正確。
 66      */
 67     if(this.packageSize % 4 != 0) this.packageSize = parseInt(this.packageSize / 4) * 4;
 68    
 69     this.onSendFinished = conf.onSendFinished || null;
 70     this.onSending = conf.onSending || null;
 71     this.onError = conf.onError || null;
 72 }
 73 FireFoxFileSender.prototype = {
 74     /*
 75      * 記錄當前發(fā)送的數據
 76      */
 77     currentData : null,
 78     /*
 79      * 記錄讀取位置
 80      */
 81     position : 0,
 82     /*
 83      * 數據大小。該值為base64字符串的長度。
 84      */
 85     length : -1,
 86     /*
 87      * 檢查錯誤隊列,嘗試觸發(fā)onError事件
 88      */
 89     checkError : function(){
 90         if(this.errMsg.length > 0){
 91             /*
 92              * 觸發(fā)onError事件
 93              */
 94             typeof this.onError == 'function' && this.onError(this.errMsg);
 95             return;
 96         }
 97     },
 98     /*
 99      * 創(chuàng)建XMLHttpRequest
100      */
101     createSender : function(){
102         var xhr = new XMLHttpRequest();
103         xhr.open('POST', this.url, true);
104         var _ = this;
105         xhr.onreadystatechange = function(){
106             /*
107              * 當服務器段響應正常,則循環(huán)讀取發(fā)送。
108              */
109             if(xhr.readyState == 4 && xhr.status == 200){
110                 /*
111                  * 觸發(fā)onSending事件
112                  */
113                 if(typeof _.onSending == 'function') _.onSending(_, xhr);
114                 /*
115                  * 延時發(fā)送下一次請求,否則服務器負擔過重
116                  */
117                 var send = setTimeout(function(){
118                     _.send();
119                     clearTimeout(send);
120                     send = null;
121                 }, 100);               
122             }
123         }
124         return xhr;
125     },
126     /*
127      * 發(fā)送數據
128      */
129     send : function(){
130         this.checkError();
131         /*
132          * 獲取當前要發(fā)送的數據
133          */
134         this.currentData = this.data.substr(this.position, this.packageSize);
135         /*
136          * 更改postion,模擬數據流移位
137          */
138         this.position += this.currentData.length;
139         /*
140          * 如果讀取字符串長度大于0,則發(fā)送該數據
141          * 否則觸發(fā)onSendFinished事件
142          */
143         if(this.currentData.length > 0) {
144             var xhr = this.createSender();
145             /*
146              * 自定義頭部信息,通知服務器端文件相關信息
147              * 實際應用時可修改此部分。
148              */
149             xhr.setRequestHeader('#FILE_NAME#', this.fileName);
150             xhr.setRequestHeader('#FILE_SIZE#', this.length);
151             xhr.setRequestHeader('#CONTENT_TYPE#', this.contentType);
152            
153             xhr.send(this.currentData);
154         } else if(typeof this.onSendFinished == 'function') {
155             /*
156              * 觸發(fā)onSendFinished事件
157              */
158             this.onSendFinished(this);
159         }
160     },
161     /*
162      * 計算已發(fā)送數據百分比
163      */
164     percent : function(){
165         if(this.length <= 0 ) return -1;
166         return Math.round((this.position / this.length) * 10000) / 100;
167     },
168     onSendFinished : null,    //該事件是以本地數據發(fā)送完成為觸發(fā),并不是服務器端返回的完成信息。
169      onSending : null,
170     onError : null
171 }
172
173  /*
174  * 上傳按鈕事件
175  */
176  function%3

到此,相信大家對“FireFox瀏覽器如何使用Javascript上傳大文件”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI