当CodeIgniter框架遇到Web Uploader上传组件
代码脚本 2016-10-04 00:18 1396阅读
在开发后台添加内容页面的时候,有一个字段是保存图片路径,而图片需要由本地上传到服务器,然后由服务器返回图片的远程路径,而且上传图片最好是页面无刷新的。页面无刷新现在已经很容易通过ajax来实现。但是如何通过ajax把文件上传到远程服务器上去呢,这就是一个问题了,本文给出了一个完整的方案。
首先要介绍一些CodeIgniter框架和Web Uploader上传组件
CodeIgniter 是一个小巧但功能强大的 PHP 框架,作为一个简单而“优雅”的工具包,它可以为开发者们建立功能完善的 Web 应用程序。在上一篇文章中已经进行过介绍。
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。采用大文件分片并发上传,极大的提高了文件上传效率。
下面来介绍实现完整方案的过程。
1、在展现页面中做引入webuploader的css文件
<link rel="stylesheet" type="text/css" href="<?php echo base_url();?>webuploader/webuploader.css">
2、增加文件上传表单的html代码
<div class="form-group"> <label for="proj" class="col-sm-3 control-label">项目文件:</label> <div class="col-sm-9"> <div id="uploader"> <div id="fileList" class="uploader-list"></div> <div id="filePicker">选择图片</div> <button id="btn-star" class="btn btn-default btn-uploadstar radius ml-10">开始上传</button> <input name="uploads" id="uploads" value="" class="sr-only" type="text"> </div> <?php // echo form_upload(array('type'=>'file','name'=>'proj','id'=>'proj'));?> </div> </div>
3、在</body>标签前加入javascript的脚本
<script type="text/javascript" src="<?php echo base_url();?>bootstrap/js/jquery.min.js"></script> <script type="text/javascript" src="<?php echo base_url();?>webuploader/webuploader.js"></script> <script> $list = $("#fileList"), $btn = $("#btn-star"), state = "pending", uploader; var uploader = WebUploader.create({ auto: false, swf: '<?php echo base_url();?>webuploader/Uploader.swf', // 文件接收服务端。 server: '<?php echo base_url();?>page_admin/webuploader', // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: { id: '#filePicker', innerHTML: '点击选择文件', multiple:false }, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! resize: false, // 只允许选择图片文件。 accept: { title: 'file', extensions: 'jpg,png,pdf,ppt,docx,doc', mimeTypes: 'image/*,application/*' } }); uploader.on( 'fileQueued', function( file ) { var $li = $( '<div id="' + file.id + '" class="item">' + '<div class="pic-box"><img></div>'+ '<div class="info">' + file.name + '</div>' + '<p class="state">等待上传...</p>'+ '</div>' ), $img = $li.find('img'); $list.append( $li ); // 创建缩略图 // 如果为非图片文件,可以不用调用此方法。 // thumbnailWidth x thumbnailHeight 为 100 x 100 var thumbnailWidth = 100; var thumbnailHeight = 100; uploader.makeThumb( file, function( error, src ) { if ( error ) { $img.replaceWith('<span>不能预览</span>'); return; } $img.attr( 'src', src ); }, thumbnailWidth, thumbnailHeight ); }); // 文件上传过程中创建进度条实时显示。 uploader.on( 'uploadProgress', function( file, percentage ) { var $li = $( '#'+file.id ), $percent = $li.find('.progress-box .sr-only'); // 避免重复创建 if ( !$percent.length ) { $percent = $('<div class="progress-box"><span class="progress-bar radius"><span class="sr-only" style="width:0%"></span></span></div>').appendTo( $li ).find('.sr-only'); } $li.find(".state").text("上传中"); $percent.css( 'width', percentage * 100 + '%' ); }); // 文件上传成功,给item添加成功class, 用样式标记上传成功。 uploader.on( 'uploadSuccess', function( file,rep) { var response = eval(rep); if(response.code === 201) { $( '#'+file.id ).addClass('upload-state-success').find(".state").text("已上传"); $('#uploads').val(response.message); }else { $( '#'+file.id ).addClass('upload-state-error').find(".state").text(response.message); } }); // 文件上传失败,显示上传出错。 uploader.on( 'uploadError', function( file ) { $( '#'+file.id ).addClass('upload-state-error').find(".state").text("上传出错"); }); // 完成上传完了,成功或者失败,先删除进度条。 uploader.on( 'uploadComplete', function( file ) { $( '#'+file.id ).find('.progress-box').fadeOut(); }); uploader.on('all', function (type) { if (type === 'startUpload') { state = 'uploading'; } else if (type === 'stopUpload') { state = 'paused'; } else if (type === 'uploadFinished') { state = 'done'; } if (state === 'uploading') { $btn.text('暂停上传'); } else { $btn.text('开始上传'); } }); $btn.on('click', function () { if (state === 'uploading') { uploader.stop(); } else { uploader.upload(); } return false; }); </script>
这里对其中的代码做一下解释,jquery.min.js和webuploader.js是必须要引入的
server: '<?php echo base_url();?>page_admin/webuploader' 是文件上传的接口。
// 文件上传成功,给item添加成功class, 用样式标记上传成功。 uploader.on( 'uploadSuccess', function( file,rep) { var response = eval(rep); if(response.code === 201) { $( '#'+file.id ).addClass('upload-state-success').find(".state").text("已上传"); $('#uploads').val(response.message); }else { $( '#'+file.id ).addClass('upload-state-error').find(".state").text(response.message); } });
这段代码是对webuploader的成功上传事件的处理,在测试的时候发现有一个bug是这样的,webuploader配置了可以上传的文件后缀名,比如.jpg,意思是说webuploader限制只能上传jpg的图片;而CodeIgniter的upload类也可以设置允许上传到文件后缀名,比如设置为.png,这样理论上webuploader可以选择一张.jpg的图片提交,但是在服务端会提示上传失败,然而,weuploader的uploadSuccess依然会判断为文件上传成功,因此,在处理uploadSuccess时间的响应时,增加了一层根据响应的json内容的判断。
4、服务端的接口代码
基于CodeIgniter的框架,只需要在控制器中增加一个webuplaoder方法就可以了,代码如下
public function webuploader() { $config['upload_path'] = './uploads/proj'; $config['allowed_types'] = 'doc|docx|pdf|ppt|jpg|png'; $config['max_size'] = 10000; $config['file_ext_tolower'] = TRUE; $config['overwrite'] = TRUE; $config['encrypt_name'] = TRUE; $this->load->library('upload', $config); $this->output->set_header('Content-Type: application/json;charset=utf-8'); if ( ! $this->upload->do_upload('file')) { $error = array('error' => $this->upload->display_errors()); echo '{"jsonrpc" : "2.0", "code": 101, "message": "'.implode($error).'"}'; } else { $upload_data = $this->upload->data(); $uploads = $upload_data['full_path']; $uploads = str_replace(str_replace('\','/', getcwd()), '', $uploads); echo '{"jsonrpc" : "2.0", "code": 201, "message": "'.$uploads.'"}'; } }
这一段里的$config是upload的配置,包括上传的文件夹,运行上传的文件类型,以及最大可以上传的文件大小,然后根据上传的结果返回成功或者失败的json。
总结
以上就是基于CodeIgniter框架作为后端脚本,结合Web Uploader上传组件制作无刷新文件上传的全部过程。其特点除了可以无刷新上传文件,由于Web Uploader支持大文件分割成小的文件块上传,这样可以避免服务器端php上传文件最大值的限制,还有双重的文件上传类型设置,完美的杜绝了非允许文件类型的上传。
喜欢请常来,打赏请随意。