摘要:背景在項目中發現,文件下載時有可能出現文件不完全導致的文件無法打開的情況,考慮在后臺響應中加入文件,與前臺取得文件后生成的值作一次校驗,來判斷文件是否正確下載。
背景
在項目中發現,文件下載時有可能出現文件不完全導致的文件無法打開的情況,考慮在后臺響應中加入文件MD5,與前臺取得文件后生成的MD5值作一次校驗,來判斷文件是否正確下載。
問題此功能的難點是如何在response中加入MD5值。原文件下載接口中使用的是HttpServletResponse,然后在前臺使用a標簽的點擊事件來實現,在開發過程中,首先想到的是在response的headers中加入MD5信息,然后在前臺想辦法取到,即
... // response.setHeader("md5",md5sum(bytes)); ... private String md5sum(byte[] bytes){ ... }
在實際開發中發現,這個方法無法正常下載文件,所以應該通過其他途徑來實現。(這種想法還是很天真的2333)
方案之前的開發中有用到Blob對象,在前臺中可以使用Blob對象來實現文件下載,即
... var url = window.URL.createObjectURL(blob); var a = document.createElement("a"); a.href = url; a.download = filename; a.click(); ...
那么肯定可以在后臺接口中加上文件的bytearray,再在JS中使用var blob = new Blob([bytearray]);來聲明一個blob對象實現文件下載,那么也可以在返回的JSON中加入生成的MD5值了。
代碼后臺
import org.apache.commons.io.IOUtils; import java.util.HashMap; import java.util.Map; import java.io.*; import java.security.MessageDigest; ... private final char HEX_DIGITS[] = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; ... @Override public Object downloadFile(String burketName, String fileName){ try { InputStream is = ...; byte[] byteArray = IOUtils.toByteArray(is); String fileMD5 = md5sum(byteArray); Map map = new HashMap(); map.put("file",byteArray); map.put("md5",fileMD5.toUpperCase()); if(is!=null){ is.close(); } return map; }catch (Exception ex){ ex.printStackTrace(); } return ""; } private String toHexString(byte[] b) { StringBuilder sb = new StringBuilder(b.length * 2); for (int i = 0; i < b.length; i++) { sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]); sb.append(HEX_DIGITS[b[i] & 0x0f]); } return sb.toString(); } private String md5sum(byte[] byteArray) { InputStream is = new ByteArrayInputStream(byteArray); byte[] buffer = new byte[1024]; int numRead = 0; MessageDigest md5; try{ md5 = MessageDigest.getInstance("MD5"); while((numRead=is.read(buffer)) > 0) { md5.update(buffer,0,numRead); } return toHexString(md5.digest()); } catch (Exception e) { System.out.println("parse md5 error"); return null; } } ...
前臺
... // 前臺在生成MD5時使用了SparkMD5插件 fetch(url, {headers:headers).then(function (res) { return res.json(); }).then(function (blob) { var spark = new SparkMD5.ArrayBuffer(); //這個是接口中返回的MD5 var serverMD5=blob.md5; var byteBuffer=_base64ToArrayBuffer(blob.file); spark.append(byteBuffer); var clientMD5 = spark.end().toUpperCase(); // 判斷文件是否下載完全 if(serverMD5 === clientMD5){ var f = new Blob([byteBuffer]); var url = window.URL.createObjectURL(f); var a = document.createElement("a"); a.href = url; a.download =filename; a.click(); window.URL.revokeObjectURL(f); } else{ console.log("文件下載時出錯,請重新下載"); } }); function _base64ToArrayBuffer (base64) { var binary_string = window.atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); for (var i=0;i總結 以上就是在開發文件下載校驗時的思路和代碼分享,開發的關鍵就是在文件下載接口返回值中加入后臺計算的文件MD5,主要就是通過后臺接口中返回文件的bytearray和用作校驗的MD5值,前臺接收到接口返回后生成一個MD5來與接口返回的MD5作校驗,再在前臺中使用返回的bytearray,通過Blob來實現文件下載。
如果你還有更好的方案,歡迎給我留言,不勝感激。
傳送門Blob: Blob
SparkMD5: SparkMD5
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97960.html
摘要:背景在項目中發現,文件下載時有可能出現文件不完全導致的文件無法打開的情況,考慮在后臺響應中加入文件,與前臺取得文件后生成的值作一次校驗,來判斷文件是否正確下載。 背景 在項目中發現,文件下載時有可能出現文件不完全導致的文件無法打開的情況,考慮在后臺響應中加入文件MD5,與前臺取得文件后生成的MD5值作一次校驗,來判斷文件是否正確下載。 問題 此功能的難點是如何在response中加入M...
摘要:綜上,對稱加密安全性低,若要稍微提高點安全性,就會提升程序復雜度。對于它的缺點數據內容泄露,其實在傳輸過程中不泄露,保存在本地同樣會泄露,若對此在意,可以對腳本文件再加一層簡單的對稱加密。 使用 JSPatch 有兩個安全問題: 傳輸安全:JS 腳本可以調用任意 OC 方法,權限非常大,若被中間人攻擊替換代碼,會造成較大的危害。 執行安全:下發的 JS 腳本靈活度大,相當于一次小型更...
閱讀 1355·2019-08-30 15:44
閱讀 2099·2019-08-30 11:04
閱讀 518·2019-08-29 15:17
閱讀 2540·2019-08-26 12:12
閱讀 3133·2019-08-23 18:09
閱讀 922·2019-08-23 15:37
閱讀 1522·2019-08-23 14:43
閱讀 2920·2019-08-23 13:13