摘要:選擇文件談到文件上傳,不得不提,中文名叫表單。當需要使用回調(diào)函數(shù)來處理上傳完成后后端返回的數(shù)據(jù)時,需要和后端預先達成約定,如,回調(diào)函數(shù)名,參數(shù)列表,等等。后端可以根據(jù)邊界的檢驗,識別上傳的文件,讀取元數(shù)據(jù)中的文件屬性,從而為驗證提供數(shù)據(jù)。
引子
其實很早就開始醞釀這一篇了,無奈總是發(fā)現(xiàn)有缺漏的地方,遂努力惡補前端+后端+底層相關知識。今天終于可以發(fā)表了。
--跟生孩子一樣啊。
選擇文件談到文件上傳,不得不提 form,中文名叫表單。它可以包含一個用來選擇文件的東東,叫做 file。
action 表示表單的數(shù)據(jù)發(fā)送的目標地址,method 表示發(fā)送表單所使用的 http 方法(get / post),enctype表示數(shù)據(jù)的編碼方式,對于文件上傳,必須為 multipart/form-data。
具體的定義參見 form。
下面是對應的頁面,可以看到,有一個提示選擇文件的按鈕
點擊按鈕,就可以選擇文件啦。
小貼士:文件選擇好之后,可以通過 FileReader 進行預覽,或者簡單的編輯。
如何上傳簡單的上傳,只需要提交對應的 form 就可以了。是不是很簡單,O(∩_∩)O哈哈哈~。
增強實現(xiàn)上面介紹的都太簡單粗暴膚淺了,實際項目中老板,客戶100%會投反對票。因為實在是太簡陋了。
美化選擇按鈕瀏覽器提供的原生控件實在是丑的不忍心看,可以自己畫一個好看的按鈕。
.chooseFile{ min-width: 30px; min-height: 15px; width: 106px; height: 29px; background-color: #B6E2C9; color: black; font-family: monospace; font-weight: 400; border-color: white; border-radius: 17px; padding: 5px; text-align: center; vertical-align: middle; cursor: pointer; }
記得把原來的form隱藏掉。
接下來你需要做的是給這個按鈕綁定 click listener ,當它被點擊時,觸發(fā) form 中的 file 的 click 事件。
不想刷新頁面有些時候,希望上傳時不刷新當前頁面。但是使用 form 是避免不了頁面刷新的。怎么辦?
第一個想出這個辦法的肯定是個頭腦靈活的家伙--使用隱藏的 iframe 上傳。
原理是,在當前頁面(父頁面)中添加 iframe,iframe 的頁面(子頁面)中包含 form 和相關的函數(shù)(驗證,預處理等等)。當用戶在父頁面點擊選擇文件的按鈕時,去觸發(fā)子頁面中 file 控件的 click 事件。
當用戶提交時,提交子頁面中的 form。這時,子頁面跳轉(zhuǎn),而父頁面沒有刷新。
這個方案有個缺點,就是需要前后端協(xié)同工作。
當需要使用回調(diào)函數(shù)來處理上傳完成后后端返回的數(shù)據(jù)時,需要和后端預先達成約定,如,回調(diào)函數(shù)名,參數(shù)列表,等等。這對前后端完全分離的開發(fā)場景(比如,你只是開發(fā)前端UI)是一個挑戰(zhàn)。(出現(xiàn)全棧工程師的原因,是不是就是因為前端工程師想把這些依賴但是卻又無法完全控制的工作給搶過來?)
比如,父頁面須定義回調(diào)函數(shù)
function uploadSuccess (result){ ... }
后端須對action(上面form中定義的/upload)返回html,html包含對回調(diào)函數(shù)的調(diào)用,以及制定參數(shù)。
...