Ajax+tp5实现多文件上传并处理
前言
有时候我们可能会碰到这样的需求:做一个用户发布动态的功能,用户可以写一些内容和上传多张图片。
比如,像下面这样:
在给用户提供较好的交互体验的前提下,我们就只能选择使用Ajax了。
实现
HTML代码
<form enctype="multipart/form-data"> <input type="text" id="content" name="content"> <!-- 多文件上传 --> <input type="file" name="upload" id="upload" multiple>
<button type="button" onclick="uploadHandle">提交</button> </form>
FormData
接口提供了一种表示表单数据的键值对的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出,所以我们可以Ajax提交请求。
FormData.append()方法,向 FormData
中添加新的属性值,FormData
对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。
JS代码
<script> var imgFiles = []; // 要上传的图片 $('#upload').change(function () { let f = this.files; /** * TODO: * 1. 可以对上传图片的数量和图片格式进行限制 * 2. 图片预览 */ for ( let item of f ){ console.log(item); imgFiles.push(item); } // 解决无法上传相同图片的问题 this.value = null; }); function uploadHandle() { let form = new FormData(); form.append('content', $('#content').content.val()); $.each(imgFiles, function ( i, file ) { form.append('files[]', file); }); submitHandle(form); } function submitHandle(formData) { $.ajax({ type: 'post', url: '', data: formData, dataType: 'json', contentType: false, processData: false, success: function (msg) { console.log(msg); }, }); } </script>
这里要注意几点:
- processData:(默认: true) 默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。以上是Jquery API文档中的描述,这里我们的data是一个FormData对象,我们不希望对数据做处理。
- contentType:(默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。因为是由form表单构造的
FormData
对象,且已经声明了属性enctype="multipart/form-data",所以这里设置为false。当然,我们也可以直接设置 contentType: "multipart/form-data”。
后台处理
接收数据
// tp5(ThinkPHP) $conent = $this->request->post('content'); $files = $this->request->file('files');
// 上传处理
$fileinfo = $this->multipleImgUpload($files);
// TODO
// 原生php $content = $_POST['content']; $files = $_FILES['files'];
处理多图片上传
// tp5
// 要么全部上传成功,要么失败 public function multipleImgUpload($files) { $flag = true; foreach ($files as $item){ if ( $item ) { $upload = $item->validate(['size' => 1024 * 1024 * 10, 'ext' => 'jpg,jpeg,png'])->move(APP_PATH . '../public/uploads/'); if ($upload) { // 上传成功 $save_path = '/uploads/' . $upload->getSaveName(); $img_src[] = $save_path; } else { $data = ['code' => 0, 'save_path' => '', 'msg' => $item->getError()]; $flag = false; } } else { $data = ['code' => 0, 'save_path' => '', 'msg' => '文件未上传']; $flag = false; } if ( !$flag ){ break; } } if ( $flag ){ $data = ['code'=>1, 'save_path'=>$img_src, 'msg'=>'']; } return $data; }