/*
* 以下是服务器端对发送数据的简单响应
* - 假如有数据被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版本,其他浏览器是否可以运行未做测试。】
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 < 1){ this.errMsg.push('Error: Not select a file.'); }
39 else {
40 this.fileName = this.f.value;
41 /*
42 * 在尝试直接发送二进制流时失败,改用发送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 * 发送数据包的大小。默认100kb
62 */
63 this.packageSize = conf.packageSize || 102400;
64 /*
65 * 每次发送数据包大小应为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 * 记录当前发送的数据
76 */
77 currentData : null,
78 /*
79 * 记录读取位置
80 */
81 position : 0,
82 /*
83 * 数据大小。该值为base64字符串的长度。
84 */
85 length : -1,
86 /*
87 * 检查错误队列,尝试触发onError事件
88 */
89 checkError : function(){
90 if(this.errMsg.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 <= 0 ) return -1;
166 return Math.round((this.position / this.length) * 10000) / 100;
167 },
168 onSendFinished : null, //该事件是以本地数据发送完成为触发,并不是服务器端返回的完成信息。
169 onSending : null,
170 onError : null
171 }
172
173 /*
174 * 上传按钮事件
175 */
176 function%3
您可能感兴趣的文章: