找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1055|回复: 0
打印 上一主题 下一主题

FireFox浏览器使用Javascript上传大文件

[复制链接]

2560

主题

2560

帖子

7622

积分

论坛元老

Rank: 8Rank: 8

积分
7622
跳转到指定楼层
楼主
发表于 2018-2-14 08:11:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

            本程序是利用3.x的Firefox浏览器可以读取本地文件的特性,实现通过xmlHttPRequest上传大文件功能,并在可以上传过程中动态显示上传进度。略加修改,并与服务器端配合,可以实现断点续传等诸多功能。
本例主要是研究FireFox的file-input节点的一些特性,其他客户端应用,如Flash、Sliverlight等,在实现客户端大文件上传时,在数据传输与服务器端存储等方面,与本例的思路基本一致。
注意:文件体积似乎有临界点,但这个临界点是多少尚未确认。建议不要用此方法上传超过100M的文件。
以下是客户端javascript代码
[U]复制代码[/U] 代码如下:
/*
* FireFoxFileSender version 0.0.0.1
* by MK winnie_mk(a)126.com
*
* 【本程序仅限于FireFox3.x版本,其他浏览器是否可以运行未做测试。】
* 【测试通过:FireFox 3.6.8 / Apache/2.2.11 (Win32) php/5.2.6 】
* ******************************************************************************
* 本程序是利用3.x的FireFox浏览器可以读取本地文件的特性
* 实现通过xmlhttpRequest上传大文件功能
* 并在可以上传过程中动态显示上传进度
* 略加修改,并与服务器端配合,可以实现断点续传等诸多功能
* 本例主要是研究FireFox的file-input节点的一些特性
* 其他客户端应用,如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  0){
            /*
             * 触发onError事件
             */
            typeof this.onError == 'function' && this.onError(this.errMsg);
            return;
        }
    },
    /*
     * 创建XMLHttpRequest
     */
    createSender : function(){
        var xhr = new XMLHttpRequest();
        xhr.open('POST', this.url, true);
        var _ = this;
        xhr.onreadystatechange = function(){
            /*
             * 当服务器段响应正常,则循环读取发送。
             */
            if(xhr.readyState == 4 && xhr.status == 200){
                /*
                 * 触发onSending事件
                 */
                if(typeof _.onSending == 'function') _.onSending(_, xhr);
                /*
                 * 延时发送下一次请求,否则服务器负担过重
                 */
                var send = setTimeout(function(){
                    _.send();
                    clearTimeout(send);
                    send = null;
                }, 100);               
            }
        }
        return xhr;
    },
    /*
     * 发送数据
     */
    send : function(){
        this.checkError();
        /*
         * 获取当前要发送的数据
         */
        this.currentData = this.data.substr(this.position, this.packageSize);
        /*
         * 更改postion,模拟数据流移位
         */
        this.position += this.currentData.length;
        /*
         * 如果读取字符串长度大于0,则发送该数据
         * 否则触发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') {
            /*
             * 触发onSendFinished事件
             */
            this.onSendFinished(this);
        }
    },
    /*
     * 计算已发送数据百分比
     */
    percent : function(){
        if(this.length
/*
* 上传按钮事件
*/
function send(fileID){
    var sender = new FireFoxFileSender(
        /*
         * 上传配置文件
         */
        {
            /*
             * input file 元素,可以是dom节点,也可以是id的字符串值
             */
            file : fileID,
            /*
             * 接收上传数据的服务器端地址
             */
            url : 'UPLOADER.php',
            /*
             * 每次发送数据包的大小。可根据服务器具体情况更改。IIS6默认为200K
             */
            packageSize : '200000',
            /*
             * 出现错误时触发该事件。本例仅在初始化时判断各参数是否齐备,并没有抛出发送过程中的错误。
             */
            onError : function(arrMsg){
                alert(arrMsg.join('\r\n'));
                sender = null;
                delete sender;
            },
            /*
             * 发送过程中触发该事件。本例中主要用于显示进度。
             */
            onSending : function(sd, xhr){
                var per = sd.percent();
                document.getElementById('Message').innerHTML = per + '% ';
                /*
                 * 该判断是在最后一次发送结束后,通过xhr的onreadystatechange事件触发的
                 * 如果传输过程中没有其他错误,基本可以确定为服务器端接收完成
                 */
                if(parseInt(per) == 100){ alert('服务器端接收完成'); }
            },
            /*
             * 该事件仅仅为【本地数据发送完成】时触发。
             * 请区别本地数据发送完成和服务器端返回完成信息这两种情况
             * 本例中并没有对服务器接收信息的情况做响应
             * 即使服务器端没有接收和保存任何数据
             * 只要确保xhr返回readyState == 4 和 status == 200
             * 发送就会继续进行
             * 服务器端如何返回完成信息可以通过更改接收数据页面的代码自定实现
             * 然后通过对xhr.responseText的值来做判断
             */
            onSendFinished : function(){
                alert('本地数据发送完成');
            }
        }
    );
    sender.send();
}
以下是服务器端php代码
[U]复制代码[/U] 代码如下:
/*
* 获取输入信息
*/
$b64 = file_get_contents("php://input");
/*
* 获取头部信息
*/
$headers = getallheaders();
$fileName = $headers['#FILE_NAME#'];
$contentType = $headers['#CONTENT_TYPE#'];
/*
* 做一些判断和处理...
*/
/*
* 以下是服务器端对发送数据的简单响应
* - 假如有数据被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';
客户端完整代码
[U]复制代码[/U] 代码如下:
  2  
  3  
  4  
  5  FireFoxFileSender - !! ONLY FOR FireFox !!
  6  
  7
  8  
  9  
10  /*
11  * FireFoxFileSender version 0.0.0.1
12  * by MK winnie_mk(a)126.com
13  *
14  * 【本程序仅限于FireFox3.x版本,其他浏览器是否可以运行未做测试。】
15  * 【测试通过:FireFox 3.6.8 / Apache/2.2.11 (Win32) PHP/5.2.6 】
16  * *********************************************************************************
17  * 本程序是利用3.x的FireFox浏览器可以读取本地文件的特性
18  * 实现通过XMLHttpRequest上传大文件功能
19  * 并在可以上传过程中动态显示上传进度
20  * 略加修改,并与服务器端配合,可以实现断点续传等诸多功能
21  * 本例主要是研究FireFox的file-input节点的一些特性
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  0){
91             /*
92              * 触发onError事件
93              */
94             typeof this.onError == 'function' && this.onError(this.errMsg);
95             return;
96         }
97     },
98     /*
99      * 创建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              * 当服务器段响应正常,则循环读取发送。
108              */
109             if(xhr.readyState == 4 && xhr.status == 200){
110                 /*
111                  * 触发onSending事件
112                  */
113                 if(typeof _.onSending == 'function') _.onSending(_, xhr);
114                 /*
115                  * 延时发送下一次请求,否则服务器负担过重
116                  */
117                 var send = setTimeout(function(){
118                     _.send();
119                     clearTimeout(send);
120                     send = null;
121                 }, 100);               
122             }
123         }
124         return xhr;
125     },
126     /*
127      * 发送数据
128      */
129     send : function(){
130         this.checkError();
131         /*
132          * 获取当前要发送的数据
133          */
134         this.currentData = this.data.substr(this.position, this.packageSize);
135         /*
136          * 更改postion,模拟数据流移位
137          */
138         this.position += this.currentData.length;
139         /*
140          * 如果读取字符串长度大于0,则发送该数据
141          * 否则触发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              * 触发onSendFinished事件
157              */
158             this.onSendFinished(this);
159         }
160     },
161     /*
162      * 计算已发送数据百分比
163      */
164     percent : function(){
165         if(this.length
            
            
您可能感兴趣的文章:
  • javascript 图片上传预览-兼容标准
  • Javascript异步表单提交,图片上传,兼容异步模拟ajax技术
  • javascript验证上传文件的类型限制必须为某些格式
  • Javascript图片上传前的本地预览实例
  • JavaScript判断文件上传类型的方法
  • javascript实现限制上传文件大小
  • JavaScript检测上传文件大小的方法
  • JavaScript设置表单上传时文件个数的方法
  • javascript实现图片上传前台页面
  • JavaScript多图片上传案例
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端