前言
有時候我們可能會碰到這樣的需求:做一個用戶發布動態的功能,用戶可以寫一些內容和上傳多張圖片。
比如,像下面這樣:
在給用戶提供較好的交互體驗的前提下,我們就只能選擇使用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; }