如何利用原生JS實現圖片預覽加上傳(前後端互動)
阿新 • • 發佈:2022-01-24
目錄
- 前言
- 效果大致如下
- 前端程式碼
- 後端程式碼
- 總結
前言
最近在寫專案的時候發現了個Vant的一個upload的圖片上傳的元件,就好奇了一下下,於是萌生了一個自己手寫一個圖片上傳的元件的想法,您猜怎麼著,還真給我實現了,那今天就和大家分享一下,大家有興趣的可以瞭解一下啦,寫進專案中可能會是個加分點哦!!
我們知道檔案上傳是需要前後端互動的,所以我這邊給出前後端程式碼。 檔案上傳大致分為以下幾個步驟
- 前端檔案選擇上傳的檔案型別
- 拿到檔案資訊
- 將選擇的檔案(視訊或圖片)在前端頁面預覽出來
- 將檔案發上傳到後端伺服器
- 客戶端能夠訪問到上傳到伺服器端的檔案
效果大致如下
前端程式碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Document</title> <style> .button{ margin-right: 20px; } #preview { display: flex; flex-wrap: wrap; width: 1500px; padding: 0 10px; justify-content: start; } .icon-po { overflow: hidden; position: relative; width: 300px; height: 300px; margin-right: 20px; margin-top: 20px; } .icon-close { position: absolute; right: 5%; top: 5%; width: 30px; height: 30px; border-radius: 50%; background-color: red; color: #fff; font-size: 12px; display: flex; align-items: center; justify-content: center; } .pic{ width: 300px; height: 300px; } </style> </head> <body> 選擇檔案(允許多檔案): <input type="file" id="f1" multiple> //multiple開啟多選 <button type="button" class="button" id="btn-submit">預覽圖片</button> <button type="button" id="complate">上傳圖片</button> <dihttp://www.cppcns.comv id="preview"></div> <br /> <script> let e = 0 let fd = new FormData() //檔案傳輸一定要使用ForData物件 let fL = [] function submitUpload() { let fileList = document.getElementById('f1').files for (let i = 0; i < fileList.length; i++) { fL.push(fileList[i]) } //渲染出圖片 //FileReader 讀取檔案的方式為readAsDataURL時會觸發 function readAndPreview(file) { // 確保 `file.name` 符合我們要求的副檔名 if (/\.(jpe?g|png|gif|mp4)$/i.test(file.name)) { //FileReader 物件允許Web應用程式非同步讀取儲存在使用者計算機上的檔案 //(或原始資料緩衝區)的內容 //這裡是讀取到input返回出來的fileList中檔案 var reader = new FileReader(); //該事件在FileReader物件讀取操作完成時觸發 reader.addEventListener("load",function () { //創建出兩個div 一個用做父容器 一個做刪除按鈕 var div1 = document.createElement('div'); var div2 = document.createElement('div'); //建立一個Image Dom 用來做渲染圖片 var dom = new Image() //當然要是想渲染視訊的話就建立一個video標籤就好啦 //給建立的Dom新增類名用於設計樣式 div1.className = 'icon-po' div2.className = 'icon-close' http://www.cppcns.comdiv2.innerHTML = 'X' dom.className = 'pic //給生成的每個圖片盒子新增index屬性 div1.index = div2.index = e e++ //給刪除按鈕新增上點選事件 div2.onclick = (e) => { console.log(e.target.index) div1.remove() fL.splice(e.target.index,1,"") console.log(fL); } //設定img的樣式 dom.width = 300; dom.height = 300; dom.title = file.name; //該 result屬性包含作為資料的資料: URL將檔案的資料表示為 base64 編碼的字串。 dom.src = this.result; //將創XMbXZRv建出的dom新增進對應的dom中去 div1.appendChild(dom) div1.appendChild(div2) preview.appendChild(div1); },false); //呼叫readAsDataURL()方法拿到result reader.readAsDataURL(file); } } //拿到input中的fileList中的檔案物件進行渲染出圖片 if (fileList) { [].forEach.call(fileList,readAndPreview); } if (!fileList.length) { alert('請選擇檔案') return } } function complate() { //篩選出未刪除的檔案 fL.forEach(async (item) => { if (typeof item === "string") { console.log(item); } else { fd.append('files',item)//將沒有別刪除的檔案加入到FormData物件中 } }) //向後端傳送請求 let xhr =http://www.cppcns.com new XMLHttpRequest() xhr.open('POST','http://localhost:3007/',true) xhr.send(fd) xhr.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { let obj = ON.parse(xhr.responseText) console.log(obj); } www.cppcns.com } } document.getElementById('btn-submit').addEventListener('click',submitUpload) document.getElementById('complate').addEventListener('click',complate) </script> </body> \ </html> 複製程式碼
後端程式碼
/** * 服務入口 */ var koaStatic = require('koa-static'); var path = require('path'); var koaBody = require('koa-body'); var fs = require('fs'); var Koa = require('koa2'); var cors = require('koa2-cors') //解決跨域 var app = new Koa(); var port = process.env.PORT || '3007'; var uploadHost = `http://localhost:3001/uploads/`; app.use(cors()) app.use(koaBody({ //koa-body 是一個可以幫助解析 http 中 body 的部分的中介軟體,包括 json、表單、文字、檔案等。 formidable: { //設定檔案的預設儲存目錄,不設定則儲存在系統臨時目錄下 uploadDir: path.resolve(__dirname,'./static') },multipart: true // 支援檔案上傳 })); app.use(koaStatic( //讓我們更加快速訪問服務中的靜態資源 path.resolve(__dirname,'./static') )); //二次處理檔案,修改名稱 app.use((ctx) => { console.log(ctx.request.files); var files = ctx.request.files.files;//得到上傳檔案的陣列 var result = []; console.log(files); let baseUrl = 'http://192.168.10.4:3007/' if (!Array.isArray(files)) {//單檔案上傳容錯 files = [files]; } files && files.forEach(item => { var path = item.path.replace(/\\/g,'/'); var fname = item.name;//原檔名稱 var nextPath = path + fname; if (item.size > 0 && path) { //得到副檔名 var extArr = fname.split('.'); var ext = extArr[extArr.length - 1]; var nextPath = path + '.' + ext; //重新命名檔案 fs.renameSync(path,nextPath); console.log(baseUrl + nextPath.slice(nextPath.lastIndexOf('/') + 1)) result.push(baseUrl + nextPath.slice(nextPath.lastIndexOf('/') + 1)); } }); ctx.body = {//向前端返回圖片上傳後的地址 "fileUrl":`${JSON.stringify(result)}` }; }) app.listen(port,() => { console.log('服務已啟動3007'); }) 複製程式碼
總結
程式碼我都做好詳細註釋啦,使用到的官方物件的作用我也給你總結出來了給你們偷個懶!!相信大家花點時間看一下就能懂啦,最後我再叨叨幾句~
- 前端
- js使用input type ="file"可以上傳檔案
- 讀取檔案完成後創建出幾個DOM用來預覽圖片,配置好相應的功能需求
- FileReader物件允許Web應用程式非同步讀取儲存在使用者計算機上的檔案(或原始資料緩衝區)的內容,使用[File]或[Blob]物件指定要讀取的檔案或資料。
- readAsDataURL方法會讀取指定的[Blob]/Blob)或[File]物件。讀取操作完成的時候,[readyState]會變成已完成DONE,並觸發loadend (en-US)事件,同時[result]屬性將包含一個data:URL格式的字串(base64編碼)以表示所讀取檔案的內容。
- FormData介面提供了一種方法來輕鬆構造一組表示表單欄位及其值的鍵/值對,然後可以使用該[XMLHttpRequest.send()]方法向後端傳送檔案。
- 後端
- 後端這裡是使用Koa寫的
- 安裝koa2-cors防止跨域
- 安裝koa-body拿到前端傳來的檔案,並存在相應的目錄下
- 安裝Koa-static然後端更加方便的訪問到上傳的檔案地址
到此這篇關於如何利用原生JS實現圖片預覽加上傳的文章就介紹到這了,更多相關JS實現圖片預覽上傳內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!