做微信企业号的时候,在‘我的日志'功能模块里边需要添加一个上传文件的功能,并且要显示上传过程中的进度条和提交后的文件名列表,于是做了基于ajax的文件上传,UI用的是MUI框架,后台是TP框架
前端代码如下:
<div class="maven-form-file">
<button type="button" class="mui-btn mui-btn-primary mui-icon mui-icon-plus maven-btn-file">选择文件</button>
<input type="file" id="doc-form-file" multiple="multiple">
<div id="demo" class="mui-progressbar">
<span></span>
</div>
div id="file-list">
</div>
</div>
<input type="hidden" name="token" value='{jiujin_$token}'>
<input type="hidden" name="user_id" value='{jiujin_$user_id}'>
<input type="hidden" name="wecha_id" value='{jiujin_$wecha_id}'>
<div class="mui-button-row">
<button type="submit" class="mui-btn mui-btn-primary">确认</button>
<a href="javascript:history.back()" class="mui-btn mui-btn-danger">取消</a>
</div>
</div>
</form>
</div>
<script type="text/javascript" src="__PUBLIC__/Jiujin/js/jquery.min.js"></script>
<script type="text/javascript" src="__PUBLIC__/Wap/mui/dist/js/mui.min.js"></script>
<script>
$(function(){
// mui("#demo1").progressbar({progress:20}).show();
$('#doc-form-file').on('change', function() {
var fileNames = '';
var formData = new FormData();
formData.append("myfile",this.files[0]);
if(this.files[0]==undefined){
mui.alert('你没选文件',"提示","确定");
return false;
}
var process=0;
mui("#demo")[0].style.visibility='visible';
mui("#demo").progressbar({progress:10}).show();
$.ajax({
url: "{jiujin_:U('wap_filepost')}",
type: "POST",
data: formData,
contentType: false,//必须false才会自动加上正确的Content-Type
processData: false,//必须false才会避开jQuery对 formdata 的默认处理
xhr: function(){ //获取ajaxSettings中的xhr对象,为它的upload属性绑定progress事件的处理函数
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ //检查upload属性是否存在
//绑定progress事件的回调函数
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
}
return myXhr; //xhr对象返回给jQuery使用
},
success: function (data) {
mui("#demo")[0].style.visibility='hidden';
if (data.status ==1) {
fileNames = '<span class="mui-badge mui-badge-success">' + data.filename + '</span> <input type="hidden" name="files[]" value="'+data.id+'">';
$('#file-list').append(fileNames);
}
mui.alert(data.info,"提示","确定");
},
error: function () {
mui.alert("上传失败!","提示","确定");
}
});
function progressHandlingFunction(e){
var curr=e.loaded;
var total=e.total;
process=curr/total*100;
mui("#demo").progressbar().setProgress(process);
}
});
上传的时候用到FormData对象,将文件组装成一组用 XMLHttpRequest发送请求的键/值对。然后放到ajax的data里边,但是要给ajax设置参数
contentType: false,//必须false才会自动加上正确的Content-Type
processData: false,//必须false才会避开jQuery对 formdata 的默认处理
进度条的实现:
在ajax的xhr的回调函数里,给他的upload属性添加onprogress事件回调,在回调函数里添加进度条的样式,回调函数的e对象里边包含loaded属性(已上传的大小),和total属性(文件的总大小),通过这个比例计算进度。
后台php控制器的代码如下:
public function wap_filepost()
{
if (IS_POST) {
if(empty($_FILES['myfile'])){
$this->error('文件为空');
}
$file_type = explode('.', $_FILES['myfile']['name']);
$new_file_name = $this->getToken(6) . time() . '.' . $file_type[1] ;
$save_path = 'D:/www/qiye/Uploads/TempFile/file/' . $new_file_name;
if (strstr('txt,xml,pdf,zip,doc,ppt,xls,docx,pptx,xlsx,png,jpg,jpeg,bmp,gif', $file_type[1]) == false) {
$this->error('只能上传txt,xml,pdf,zip,doc,ppt,xls,docx,pptx,xlsx,png,jpg,jpeg,bmp,gif格式!');
exit();
}
if (file_exists($save_path)) {
$this->ajaxReturn(array('status'=>0, 'info'=>'文件已存在'));
}
else {
move_uploaded_file($_FILES['myfile']['tmp_name'], $save_path);
}
$file_url = 'http://' . $_SERVER['HTTP_HOST'] .'/Uploads/TempFile/file/'. $new_file_name;
$id = M('Qyfile')->add(array('user_id' => $_SESSION['user_id'], 'media_id' =>'', 'created_time' => time(), 'type' => 'file', 'path' => $file_url, 'title' => $_FILES['myfile']['name']));
$this->ajaxReturn(array('status'=>1, 'info'=>'上传成功', 'url'=>$file_url, 'filename'=>$_FILES['myfile']['name'],'id'=>$id));
}
}
因为前端newdate.append("myfile",files[0]);所以后台需要用$_FILES['myfile']拿值,其他就是后台的逻辑了