一次Ionic3上傳圖片的經(jīng)歷

概述

  • 本文只是回顧這樣一次經(jīng)歷,所以不會貼大段大段代碼
  • 當(dāng)時拿到的需求是,先在手機上寫好簽名,然后上傳到服務(wù)器持久化到數(shù)據(jù)庫,最后供web和移動端以圖片的形式展示出來。

過程

第一反應(yīng)是這功能有啥用,默默地吐槽完領(lǐng)導(dǎo)后開始考慮怎么去實現(xiàn)。

需求的理解

  • 最先想到的是手機輸入法的手寫功能,去訊飛看了一下,基本上都是說的語音識別(因為最近人工智能很火),沒找到手寫相關(guān)的API。正苦惱的時候發(fā)現(xiàn)自己思路跑偏了,既然是要簽名,手寫的給識別出來了就沒意義了(簽名就是要認不出來)。”寫啥樣就要存啥樣”,這不就是畫畫嘛。
  • 于是轉(zhuǎn)向了canvas。其實對canvas我的了解僅僅局限于這是能在頁面上畫畫的。接下來就是去找ionic有沒有相關(guān)的插件,結(jié)果找到了signature_pad.js,更幸福的是,已經(jīng)有人在ionic上用過。

如何實現(xiàn)

  • 在github上作者也詳細介紹了怎么使用,如何導(dǎo)出成圖片。實踐的過程中發(fā)現(xiàn)可以導(dǎo)出為.jpg,.png,.svg三種格式。但是導(dǎo)出的內(nèi)容是”dataurl”,對于在此之前僅僅知道圖片本質(zhì)也是二進制的我而言,新的問題出現(xiàn)了。怎么把dataurl轉(zhuǎn)換成真正的圖片呢?
  • 這時候需求增加了。需要在手機端本地存儲這張圖片,以便以后直接調(diào)用,減少一次請求。
  • 這實際上還是之前的問題,dataurl→圖片。”內(nèi)事不決問百度”。經(jīng)過一番搜索后,發(fā)現(xiàn)dataurl可以轉(zhuǎn)為Blob對象,通過Blob對象能夠生成一個文件。

ionic本地文件系統(tǒng)

  • 在ionic中獲取設(shè)備文件系統(tǒng),進而取得文件路徑,最后寫入文件內(nèi)容,這個問題已經(jīng)解決了。通過cordova-plugin-file這個插件就能解決該問題。
  • 到這個時候,我認為問題已經(jīng)完全解決了,既然dataurl在手機本地能夠直接轉(zhuǎn)為圖片,那么在服務(wù)器上自然也能轉(zhuǎn)為圖片,最后再把圖片路徑持久化到數(shù)據(jù)庫就萬事大吉了。中間需要解決就是把dataurl發(fā)送到服務(wù)器。

圖片上傳到后臺

  • 最開始我覺得這都不是問題,發(fā)數(shù)據(jù)到服務(wù)器,post請求不就完事了。接下來,通過Angular的http模塊,設(shè)置header為applicant/x-www-form-urlencoded,再服務(wù)端通過文件上傳API生成了圖片。問題又來了。
  • dataurl在本地與在服務(wù)器生成的圖片竟然不一樣。于是在chrome控制臺看請求響應(yīng)信息。把請求中的dataurl拿出來在服務(wù)器直接本地測試,生成的圖片又是正確的。最后在服務(wù)器打斷點debug,發(fā)現(xiàn)服務(wù)器接受到的dataurl是客戶端發(fā)送的dataurl截取后的值。
  • dataurl一般會很長,可能會達到10000個字符。經(jīng)過百度后發(fā)現(xiàn),post請求本身對長度是沒有限制的,但是服務(wù)器會有,tomcat就有這方面的參數(shù)可以設(shè)置。但是服務(wù)器一般配置好了不會輕易更改,因此還是只能從自身來找解決方案。

form表單的提交方式

  • 在MDN上查看Using_XMLHttpRequest相關(guān)的頁面上了解到,form表單有四種提交方式
    • method=post, enctype=applicant/x-www-form-urlencoded 這是表單提交的默認方式
    • method=post, enctype=multipart/form-data 文件上傳時表單的提交方式
    • method=post, enctype=text/plain
    • method=get 這種情況下enctype會被忽略
  • 這時候我突然想到,圖片上傳到服務(wù)器的過程中,圖片數(shù)據(jù)是以什么形式存在的呢?我嘗試直接把dataurl放到 img 標(biāo)簽的 src 屬性中,果然,直接把圖片顯示出來了。那么文件上傳時,圖片數(shù)據(jù)可能就是把dataurl直接發(fā)送到后臺,而且因為是文件上傳,那么服務(wù)器對于請求數(shù)據(jù)的大小應(yīng)該是沒有限制或者說限制的字節(jié)數(shù)會大得多

在沒有form表單的情況下構(gòu)造文件上傳

  • 因為沒有form標(biāo)簽,沒有辦法直接通過表單提交的方式上傳圖片。有兩個備選方案:

    • 通過js生成一個form表單
    • 直接手動構(gòu)造一個文件上傳請求
  • 方案一太麻煩,不夠直接。所以直接就采用了方案二。通過FormData的API可以直接構(gòu)造表單項。

    let fd = new FormData();
    fd.append("Filename", "signature.png");
    fd.append("Filedata", params, "signature.png");
    
  • 然后在后臺方法中,直接將該dataurl寫到文件里面,就能夠生成一張 .png 圖片了

感想

  • 對需求的理解很重要。最開始拿到需求時,我的腦海里關(guān)鍵詞就是手寫。甚至都想這不是需要人工智能識別的嘛。很顯然這個思路就偏了。當(dāng)對需求的理解有偏差的時候,后面的實現(xiàn)必然會遇到各種問題。

  • 對技術(shù)原理、實質(zhì)的認識是實現(xiàn)的關(guān)鍵。在這個過程中,

    • 對圖片壓根不了解
    • 對java上傳文件不熟悉
    • 對表單相關(guān)API掌握的不夠深入

    最后完成這個功能,我發(fā)現(xiàn)自己都完整寫了一遍最原始的java文件上傳代碼,文件流相關(guān)的代碼等等...

  • 發(fā)散思維,自己不會就得找資料,現(xiàn)在開始學(xué)習(xí),一切都來得及。Never Too Old To Learn

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文包括:1、文件上傳概述2、利用 Commons-fileupload 組件實現(xiàn)文件上傳3、核心API——Dis...
    廖少少閱讀 12,744評論 5 91
  • 如果不考慮ie9兼容性,實現(xiàn)【上傳圖片】大致的思路如下: 由于公司是將所有上傳的圖片都放到【代理服務(wù)器】里。所以【...
    kakaguo閱讀 6,130評論 1 4
  • 一、文件上傳介紹 要將客戶端(瀏覽器)大數(shù)據(jù)存儲到服務(wù)器端,不將數(shù)據(jù)直接存儲到數(shù)據(jù)庫中,而是要將數(shù)據(jù)存儲到服務(wù)器所...
    圣賢與無賴閱讀 1,321評論 0 16
  • 上傳圖片我首先想到的是利用這個插件,webupload LUploade這類插件大多支持圖片預(yù)覽,斷點/分片上傳,...
    六寸星田閱讀 51,744評論 0 1
  • 在這個“大眾創(chuàng)新,萬眾創(chuàng)業(yè)”的時代,創(chuàng)業(yè)成為大學(xué)生的一個新的標(biāo)桿。例如:每年的互聯(lián)網(wǎng)+大賽,省級的創(chuàng)業(yè)大賽,市級創(chuàng)...
    老胡說創(chuàng)業(yè)閱讀 2,418評論 0 5

友情鏈接更多精彩內(nèi)容