成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

文件下載時(shí)前后臺(tái)MD5校驗(yàn)

Object / 1220人閱讀

摘要:背景在項(xiàng)目中發(fā)現(xiàn),文件下載時(shí)有可能出現(xiàn)文件不完全導(dǎo)致的文件無(wú)法打開(kāi)的情況,考慮在后臺(tái)響應(yīng)中加入文件,與前臺(tái)取得文件后生成的值作一次校驗(yàn),來(lái)判斷文件是否正確下載。

背景

在項(xiàng)目中發(fā)現(xiàn),文件下載時(shí)有可能出現(xiàn)文件不完全導(dǎo)致的文件無(wú)法打開(kāi)的情況,考慮在后臺(tái)響應(yīng)中加入文件MD5,與前臺(tái)取得文件后生成的MD5值作一次校驗(yàn),來(lái)判斷文件是否正確下載。

問(wèn)題

此功能的難點(diǎn)是如何在response中加入MD5值。原文件下載接口中使用的是HttpServletResponse,然后在前臺(tái)使用a標(biāo)簽的點(diǎn)擊事件來(lái)實(shí)現(xiàn),在開(kāi)發(fā)過(guò)程中,首先想到的是在response的headers中加入MD5信息,然后在前臺(tái)想辦法取到,即

...
// response.setHeader("md5",md5sum(bytes));
...

private String md5sum(byte[] bytes){
    ...
}

在實(shí)際開(kāi)發(fā)中發(fā)現(xiàn),這個(gè)方法無(wú)法正常下載文件,所以應(yīng)該通過(guò)其他途徑來(lái)實(shí)現(xiàn)。(這種想法還是很天真的2333)

方案

之前的開(kāi)發(fā)中有用到Blob對(duì)象,在前臺(tái)中可以使用Blob對(duì)象來(lái)實(shí)現(xiàn)文件下載,即

...
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
...

那么肯定可以在后臺(tái)接口中加上文件的bytearray,再在JS中使用var blob = new Blob([bytearray]);來(lái)聲明一個(gè)blob對(duì)象實(shí)現(xiàn)文件下載,那么也可以在返回的JSON中加入生成的MD5值了。

代碼
后臺(tái)
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;
        }
    }
...
前臺(tái)
...
// 前臺(tái)在生成MD5時(shí)使用了SparkMD5插件
fetch(url, {headers:headers).then(function (res) {
    return res.json();
}).then(function (blob) {
    var spark = new SparkMD5.ArrayBuffer();
    //這個(gè)是接口中返回的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("文件下載時(shí)出錯(cuò),請(qǐng)重新下載");
    }
});

function _base64ToArrayBuffer (base64) {
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array(len);
    for (var i=0;i
總結(jié)

以上就是在開(kāi)發(fā)文件下載校驗(yàn)時(shí)的思路和代碼分享,開(kāi)發(fā)的關(guān)鍵就是在文件下載接口返回值中加入后臺(tái)計(jì)算的文件MD5,主要就是通過(guò)后臺(tái)接口中返回文件的bytearray和用作校驗(yàn)的MD5值,前臺(tái)接收到接口返回后生成一個(gè)MD5來(lái)與接口返回的MD5作校驗(yàn),再在前臺(tái)中使用返回的bytearray,通過(guò)Blob來(lái)實(shí)現(xiàn)文件下載。

如果你還有更好的方案,歡迎給我留言,不勝感激。

傳送門(mén)

Blob: Blob

SparkMD5: SparkMD5

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77255.html

相關(guān)文章

  • 文件下載時(shí)后臺(tái)MD5校驗(yàn)

    摘要:背景在項(xiàng)目中發(fā)現(xiàn),文件下載時(shí)有可能出現(xiàn)文件不完全導(dǎo)致的文件無(wú)法打開(kāi)的情況,考慮在后臺(tái)響應(yīng)中加入文件,與前臺(tái)取得文件后生成的值作一次校驗(yàn),來(lái)判斷文件是否正確下載。 背景 在項(xiàng)目中發(fā)現(xiàn),文件下載時(shí)有可能出現(xiàn)文件不完全導(dǎo)致的文件無(wú)法打開(kāi)的情況,考慮在后臺(tái)響應(yīng)中加入文件MD5,與前臺(tái)取得文件后生成的MD5值作一次校驗(yàn),來(lái)判斷文件是否正確下載。 問(wèn)題 此功能的難點(diǎn)是如何在response中加入M...

    mingde 評(píng)論0 收藏0
  • JSPatch 部署安全策略

    摘要:綜上,對(duì)稱(chēng)加密安全性低,若要稍微提高點(diǎn)安全性,就會(huì)提升程序復(fù)雜度。對(duì)于它的缺點(diǎn)數(shù)據(jù)內(nèi)容泄露,其實(shí)在傳輸過(guò)程中不泄露,保存在本地同樣會(huì)泄露,若對(duì)此在意,可以對(duì)腳本文件再加一層簡(jiǎn)單的對(duì)稱(chēng)加密。 使用 JSPatch 有兩個(gè)安全問(wèn)題: 傳輸安全:JS 腳本可以調(diào)用任意 OC 方法,權(quán)限非常大,若被中間人攻擊替換代碼,會(huì)造成較大的危害。 執(zhí)行安全:下發(fā)的 JS 腳本靈活度大,相當(dāng)于一次小型更...

    qqlcbb 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Object

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<