摘要:必須阻止和事件的默認(rèn)行為,這樣才能觸發(fā)事件文件對象將圖片轉(zhuǎn)換為獲取到圖片內(nèi)容微信截圖上傳監(jiān)聽事件,通過剪貼板對象獲取圖片信息。但是最好的方案還是不管下載上傳都直接走獨(dú)立圖片服務(wù)器,避免對服務(wù)器造成額外的壓力。
更多文章請點(diǎn)擊Jade
接了一個「常規(guī)」需求:開發(fā)一個本地上傳圖片控件,需要支持三種上傳方式:
支持打開本地目錄,選擇本地圖片上傳
支持拖曳圖片上傳
支持微信截圖上傳
我們先從工程角度來看一下用戶上傳圖片的流程是怎樣子的:
用戶選擇了一張本地圖片,或者拖曳了一張圖片,或者通過微信截圖了一張圖片。這時,我們需要知道用戶所選擇圖片的信息,比如圖片的內(nèi)容、圖片的大小、圖片的類型等。
用戶上傳圖片。這時,我們需要保存圖片。
用戶查看圖片。這時,我們需要把第2步中保存的圖片展示給用戶。
如何獲取到圖片信息 通過input 打開本地目錄,選擇本地圖片上傳通過type為file的input標(biāo)簽選擇本地圖片上傳,每次選擇不同圖片的時候會觸發(fā)onChange事件。為什么我要強(qiáng)調(diào)不同圖片,因?yàn)楫?dāng)兩次選擇的圖片是一樣的情況下,onChange事件無法觸發(fā)。解決方法:每次處理完后手動置空input的value。
// 置空input value clearImgInputValue () { document.getElementById("img-input").value = "" } bindChooseEvents = (e) => { console.log("choose a image") // 獲取File對象 const file = e.target.files[0] let size = file.size if (!file.type.match("image.*")) { AntMessage.warning("File"s type is not supported. Images only.") this.clearImgInputValue() return; } if (size > maxSize) { AntMessage.warning("The size of the image is too large") this.clearImgInputValue() return; } /* eslint-disable */ const reader = new FileReader() // FileReader /* eslint-disable */ // 將圖片轉(zhuǎn)換為base64 reader.readAsDataURL(file) reader.onload = (arg) => { // 獲取到base64圖片內(nèi)容 const fileStream = arg.target.result /** * overwrite do something * */ this.clearImgInputValue() } }拖曳圖片上傳
監(jiān)聽拖曳事件,通過拖曳相關(guān)的DataTransfer對象獲取圖片信息。
Drop Zone
bindDragEvents = (e) => { const handleDragOver = (event) => { event.stopPropagation() event.preventDefault() event.dataTransfer.dropEffect = "copy" } // 必須阻止dragenter和dragover事件的默認(rèn)行為,這樣才能觸發(fā) drop 事件 const handleFileSelect = (event) => { event.stopPropagation() event.preventDefault() const files = event.dataTransfer.files // 文件對象 const file = files[0] const size = file.size const type = file.type if (!type.match("image.*")) { AntMessage.warning("File"s type is not supported. Images only.") return; } if (size > maxSize) { AntMessage.warning("The size of the image is too large") return; } /* eslint-disable */ const reader = new FileReader() /* eslint-disable */ // 將圖片轉(zhuǎn)換為base64 reader.readAsDataURL(file) reader.onload = (arg) => { // 獲取到base64圖片內(nèi)容 const fileStream = arg.target.result /** * overwrite do something * */ } } const dropZone = document.getElementById("drop-zone"); dropZone.addEventListener("dragover", handleDragOver, false); dropZone.addEventListener("drop", handleFileSelect, false); }微信截圖上傳
監(jiān)聽paste事件,通過剪貼板對象clipboardData獲取圖片信息。
bindClipEvents() { document.addEventListener("paste", (e) => { console.log("paste a image") const clipboard = e.clipboardData // 有無內(nèi)容 if (!clipboard.items || !clipboard.items.length) { AntMessage.warning("No content in the clipboard") return; } let item = clipboard.items[0] if (item.kind === "file" && item.type.match("image.*")) { // 獲取圖片文件 let imgFile = item.getAsFile() if (imgFile.size > maxSize) { AntMessage.warning("The size of the image is too large") return; } const reader = new FileReader() // 將圖片轉(zhuǎn)換為base64 reader.readAsDataURL(imgFile) reader.onload = (arg) => { // 獲取到base64圖片內(nèi)容 const fileStream = arg.target.result /** * overwrite do something * */ } } else { AntMessage.warning("File"s type is not supported. Images only.") } }, false) }如何保存
圖片保存一般都采用獨(dú)立圖片獨(dú)立域名服務(wù)器,不會傻乎乎地把圖片保存在web服務(wù)器上也不會直接存在項(xiàng)目表的數(shù)據(jù)庫中。這樣做有什么好處呢?
圖片訪問是I/O密集型操作,很消耗服務(wù)器資源,從Web服務(wù)器獨(dú)立出來后,能夠減少Web服務(wù)器壓力
便于擴(kuò)容、容災(zāi)和數(shù)據(jù)遷移
瀏覽器有同域名下的并發(fā)策略限制
請求圖片一般并不需要cookie,但是瀏覽器發(fā)起的所有同域名請求時,http頭部都會自動帶上cookie信息,導(dǎo)致浪費(fèi)帶寬
方便對圖片訪問做負(fù)載均衡,可以對圖片應(yīng)用各種緩存策略
方便遷移CDN
...
總結(jié)&優(yōu)化 流程圖: 不足:項(xiàng)目實(shí)踐中我們雖然采用了獨(dú)立圖片服務(wù)器,下載過程只是通過Web服務(wù)器去數(shù)據(jù)庫拿到圖片地址,但是我們的上傳操作仍舊經(jīng)過了Web服務(wù)器,需要Web服務(wù)器上的應(yīng)用程序來處理,所以上傳過程仍舊對Web服務(wù)器造成壓力。所幸的是,我們對圖片上傳大小進(jìn)行了1M的大小限制,同時作為內(nèi)部系統(tǒng)沒啥訪問壓力,而且圖片上傳功能也并不是很高發(fā)的行為,所以這么做基本也不會有啥問題。但是最好的方案還是不管下載上傳都直接走獨(dú)立圖片服務(wù)器,避免對Web服務(wù)器造成額外的壓力。
后續(xù),探究圖片服務(wù)器架構(gòu) & 如何應(yīng)對大文件的上傳 & Blob Buffer Stream三者之間的關(guān)系。 本文參考資料:理解DOMString、Document、FormData、Blob、File、ArrayBuffer數(shù)據(jù)類型
復(fù)制粘貼的高級玩法
使用FileReader.readAsArrayBuffer()在瀏覽器中處理大文件
大型網(wǎng)站圖片服務(wù)器架構(gòu)的演進(jìn)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90784.html
摘要:發(fā)布應(yīng)用市場的平臺搶紅包工具紅包精靈開源啦掘金紅包精靈,如果喜歡,點(diǎn)個開源不易。作者將原素材文章進(jìn)行了新內(nèi)容的添加和重新排列,但是因?yàn)槲恼赂咝У拇a編寫技巧總結(jié)前端掘金本文總結(jié)了代碼編寫技巧,來提升你的和代碼。 收藏安卓開發(fā)中非常實(shí)用優(yōu)秀的庫! 有圖有真相! - Android - 掘金本來是打算收藏工具類的,但轉(zhuǎn)念一想,已經(jīng)有這么多優(yōu)秀的庫了,就沒必要再去重復(fù)造輪子了,便歸納工作中比...
摘要:在開發(fā)之前你要有微信開發(fā)者工具。同時為了更適合開發(fā)微信小程序,還對進(jìn)行了擴(kuò)充以及修改,直接幫我們把適配的一部分工作都做了,比如他的,可以根據(jù)屏幕寬度進(jìn)行自適應(yīng),規(guī)定屏幕寬為。 本文由云+社區(qū)發(fā)表 這段時間有幸加入了一個關(guān)于微信小程序的項(xiàng)目開發(fā)組,從無到有的根據(jù)文檔自行學(xué)習(xí)了小程序的開發(fā)過程,前面已經(jīng)有幾位前輩的文章珠玉在前,我這里就先從前端界面的開發(fā)方面談一談小程序以及我所遇到的問題吧...
摘要:以上傳圖片為例。我們可以通過獲取上傳的圖片相關(guān)信息,但是想要實(shí)現(xiàn)本地預(yù)覽還需要借助來實(shí)現(xiàn)可以讀取本地圖片,并將圖片數(shù)據(jù)轉(zhuǎn)換成編碼的字符串形式嵌入到頁面中。在我們實(shí)現(xiàn)上傳圖片的效果里,就有用到。圖片預(yù)覽兼容處理及以下版本不支持和。 最近項(xiàng)目里需要用到上傳圖片并預(yù)覽的功能,于是寫了個jQuery預(yù)覽圖片插件,下載地址。如果有需要的,可以直接下載。第一次寫jQuery插件,如有不對之處,歡迎...
摘要:老姚淺談怎么學(xué)鑒于時不時,有同學(xué)私信問我老姚,下同怎么學(xué)前端的問題。擼碼聽歌,全局控制。 淺析用 js 解析 xml 的方法 由于項(xiàng)目上需要解析 xml,于是各種百度,然后自己總結(jié)了下各個主流瀏覽器解析 xml 的方法,只能是很淺顯的知道他的用法,但是還沒有深層次的研究。 裝 X - 建立自己的斗圖網(wǎng)站庫 之前加過一個斗圖群,看到很多經(jīng)典的表情,然后就收藏到了 QQ, 迫于本屌絲開不起...
閱讀 3764·2021-08-11 11:16
閱讀 1633·2019-08-30 15:44
閱讀 2003·2019-08-29 18:45
閱讀 2283·2019-08-26 18:18
閱讀 1013·2019-08-26 13:37
閱讀 1578·2019-08-26 11:43
閱讀 2128·2019-08-26 11:34
閱讀 386·2019-08-26 10:59