微信開發中使用微信JSSDK和使用URL.createObjectURL上傳預覽圖片的不同處理對比

来源:https://www.cnblogs.com/wuhuacong/archive/2019/10/17/11691258.html
-Advertisement-
Play Games

在做微信公眾號或者企業微信開發業務應用的時候,我們常常會涉及到圖片預覽、上傳等的處理,往往業務需求不止一張圖片,因此相對來說,需要考慮的全面一些,用戶還需要對圖片進行預覽和相應的處理,在開始的時候我使用JSSDK方式,使用微信的SDK介面進行圖片的上傳、預覽操作,後來發現通過URL.createOb... ...


在做微信公眾號或者企業微信開發業務應用的時候,我們常常會涉及到圖片預覽、上傳等的處理,往往業務需求不止一張圖片,因此相對來說,需要考慮的全面一些,用戶還需要對圖片進行預覽和相應的處理,在開始的時候我使用JSSDK方式,使用微信的SDK介面進行圖片的上傳、預覽操作,後來發現通過URL.createObjectURL選定本地圖片預覽、上傳也是非常方便的,本篇隨筆針對同一個多圖片的業務需求,使用JSSDK和URL.createObjectURL兩種方式進行圖片預覽、上傳、刪除等常規的處理。

1、使用JSSDK對圖片的處理

 在一個公眾號頁面-問診界面裡面,我們需要讓用戶上傳相關的圖片,包括癥狀圖片、處方圖片等,每個列表可以上傳多張圖片,如下界面所示。

這裡使用了SDK進行圖片的上傳處理,參考Weui的上傳樣式,選擇本地幾張圖片,可以看到縮略圖展示在圖框裡面,但是圖片還沒有上傳,我們在保存問診信息的時候,才啟動圖片文件的上傳處理。

如果圖片是在編輯界面中,我們需要考慮對現有圖片進行刪除的處理,刪除前確認即可。 

 

 單擊刪除圖標的按鈕,提示用戶進行圖片刪除確認即可。

 以上就是我們幾個圖片處理的場景,我們來看看如何實現的。

我們以癥狀圖片為例,它的界面HTML部分的代碼如下所示。

<div class="weui-cells__title">癥狀圖片</div>
<div class="weui-cells weui-cells_form">
    <div class="weui-cell">
        <div class="weui-cell__bd">
            <div class="weui-uploader">
                <!--編輯的時候,放置已有圖片進行預覽-->
                <ul class="weui-weui-uploader__files" style="list-style-type: none" id="imgSickPreview"></ul>
                <div class="weui-uploader__bd">
                    <!--放置選擇的圖片進行預覽-->
                    <ul class="weui-weui-uploader__files" style="list-style-type: none" id="imgSick"></ul>
                    <div class="weui-uploader__input-box">
                        <!--圖片上傳的圖標處理-->
                        <span id="uploaderSick" class="weui-uploader__input"></span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

為了使用微信JSSDK來實現上傳、預覽圖片的功能,我們需要定義好對應的JS介面,如下代碼所示。

    <script language="javascript">
        var appid = '@ViewBag.appid';
        var noncestr = '@ViewBag.noncestr';
        var signature = '@ViewBag.signature';
        var timestamp = '@ViewBag.timestamp';

        wx.config({
            debug: false,
            appId: appid, // 必填,公眾號的唯一標識
            timestamp: timestamp, // 必填,生成簽名的時間戳
            nonceStr: noncestr, // 必填,生成簽名的隨機串
            signature: signature, // 必填,簽名,見附錄1
            jsApiList: [
               'checkJsApi',
               'chooseImage',
               'previewImage',
               'uploadImage',
               'downloadImage',
               'getLocalImgData'
            ]
        });

......

    </script>

在上傳圖片之前,我們需要通過JSSDK的方式選擇圖片,這裡用到了chooseImage的介面,大概所需的代碼如下所示。

        //上傳圖片集合[用微信上傳的時候,記錄微信mediaId集合]
        var images = {
            localSickId: [],//病情
            localPresId: [],//處方

            serverSickId: [],
            serverPresId: []
        };

        //圖片選擇
        $("#uploaderSick").click(function () {
            chooseImage("imgSick", "sick");
        });
        $("#uploaderPres").click(function () {
            chooseImage("imgPres", "pres");
        });

        //選擇圖片顯示
        function chooseImage(ctrlName, type) {
            //清空集合
            if (type == "sick") {
                images.localSickId = [];
            } else {
                images.localPresId = [];
            }

            wx.chooseImage({
                count: 3, // 預設9
                sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,預設二者都有
                sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,預設二者都有
                success: function (res) {
                    var ctrl = $("#" + ctrlName);
                    ctrl.html("");//清空圖片顯示

                    //localIds = res.localIds; // 返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片
                    if (type == "sick") {
                        images.localSickId = res.localIds;
                    } else {
                        images.localPresId = res.localIds;
                    }

                    //動態增加img標識
                    $.each(res.localIds, function (index, item) {
                        ctrl.append("<img class='weui-uploader__file' src='" + item + "' />");
                    });
                }
            });
        }

選擇圖片後,就是將圖片的縮略圖動態的增加在指定圖片框裡面。然後在保存數據的時候,使用JSSDK提交圖片到微信伺服器,我們伺服器後臺再從微信伺服器獲取圖片(通過媒體id)。

這裡我們定義了兩類的圖片,方便區分,分別是癥狀圖片和處方圖片,因此需要定義兩個類別的變數,分別存儲本地和伺服器返回的id集合。

我們在進行表單提交的時候,需要確認一些必填項,然後在檢查是否有文件需要上傳,如果有則執行上傳處理後提交表單,大概的處理代碼如下所示。

        //上傳數據
        $("#btnOK").click(function () {
            var PatientName = $("#PatientName").val();
            if (PatientName == '' || PatientName == undefined) {
                $.toast('患者姓名不能為空', "forbidden");
                return;
            }
            var ProblemDetail = $("#ProblemDetail").val();
            if (ProblemDetail == '' || ProblemDetail == undefined) {
                $.toast('詳細描述不能為空', "forbidden");
                return;
            }

            //上傳圖片
            if (images.localSickId.length > 0 || images.localPresId.length > 0) {
                uploadImage(submitCallback);//通過就提交數據
            } else {
                submitCallback();
            }
        });

這裡主要的圖片上傳處理,就是 uploadImage 函數的處理了,而submitCallback這是定義一個函數上傳表單數據的。

由於微信JSSDK上傳圖片,是一個個上傳的,我們需要把它們串聯起來,一併上傳。uploadImage 裡面定義了一個內部函數,依次進行圖片的上傳。

我們通過序號來標識兩類圖片,圖片上傳成功後,我們把圖片媒體的id(JSSDK返回的)記錄下來,統一提交給對應資料庫記錄,在後臺進行圖片文件的提取即可。

        //上傳圖片
        function uploadImage(callback) {
            var localIds = images.localSickId.concat(images.localPresId);//合併數組
            var i = 0, length = localIds.length;
            //$.toast(length);

            images.serverSickId = [];
            images.serverPresId = [];

            //定義一個子級函數,方便遞歸調用
            function upload(callback) {
                wx.uploadImage({
                    localId: localIds[i],
                    success: function (res) {
                        i++;

                        //成功後加入不同的集合
                        if (i <= images.localSickId.length) {
                            images.serverSickId.push(res.serverId);//第一部分
                        } else {
                            images.serverPresId.push(res.serverId);//第二部分
                        }

                        if (i < length) {
                            upload(callback);
                        }else if (callback != undefined) {
                            callback();//回調函數
                        }
                    },
                    fail: function (res) {
                        alert(JSON.stringify(res));
                    }
                });
            };

            upload(callback);
        }

其中我們的定義的callback函數,是用來最後上傳完成後,執行表單的記錄存儲的,表單包含各種輸入和圖片的ID信息,如下是詳細的表單保存操作代碼。

        //在上傳圖片後觸發的回調函數
        function submitCallback() {
            var druglist = [];//構造集合對象
            for (var key in itemDict) {
                //Drug_ID,DrugName,How,Freq
                druglist.push({
                    'Drug_ID': key, "DrugName": itemDict[key], 'How': howDict[key],
                    'Freq': freqDict[key], 'Quantity': quantityDict[key]
                });
            }
            var url = "/H5/[email protected]";
            var postData = {
                PatientName: $("#PatientName").val(),
                Gender: $("#Gender").val(),
                BirthDate: $("#BirthDate").val(),
                Telephone: $("#Telephone").val(),
                ProblemDetail: $("#ProblemDetail").val(),
                Creator: $("#Creator").val(),
                ProblemItems: $("input[name='ProblemItems']:checked").val(),
                @if (ViewBag.Info != null) { 
                <text>
                ID: '@ViewBag.Info.ID',
                </text>
                }

                SickAttachGUID: $("#SickAttachGUID").val(),
                PresAttachGUID: $("#PresAttachGUID").val(),
                ServerSickId: JSON.stringify(images.serverSickId),
                ServerPresId: JSON.stringify(images.serverPresId),
                DrugList: JSON.stringify(druglist)
            };

            $.post(url, postData, function (json) {
                //轉義JSON為對象
                var data = $.parseJSON(json);
                if (data.Success) {
                    $.toast("處方已提交審核中,稍後請到處方查詢查看。");
                    //WeixinJSBridge.call('closeWindow');//關閉視窗
                    location.href = "/h5/Prescription";//跳轉到處方頁面
                }
                else {
                    $.toast("保存失敗:" + data.ErrorMessage, "forbidden");
                }
            });
        };

我們註意到,我們服務端返回的ID集合,我們分別放在了兩個欄位裡面提交到後臺處理。

    ServerSickId: JSON.stringify(images.serverSickId),
    ServerPresId: JSON.stringify(images.serverPresId),

在後臺,我們首先需要提取用戶提交的基礎表單數據,如下是後臺定義的函數處理

 

 這些是常規的表單信息,我們提交到微信伺服器的圖片信息也需要提取出來的,這些圖片分兩類,每類都包含多個字元串組成的圖片ID集合。

後臺主要就是根據這些ID,使用微信基礎介面,獲取臨時圖片的介面方式,把圖片從伺服器上下載下來存儲到本地伺服器上。

 其中UploadFile函數就是封裝瞭如何實現圖片獲取、圖片存儲的處理邏輯,主要的代碼部分邏輯如下所示。

 這種方式很好的利用了JSSDK的圖片選擇、上傳的處理,實現了我們所需要的圖片預覽、選擇、上傳等一系列操作,也能夠滿足實際的功能需要。

不過總感覺把圖片繞了一圈再回來不太好而已。

2、使用URL.createObjectURL對圖片的處理

 前面介紹了使用微信JSSDK方式實現圖片預覽、選擇、上傳等一系列操作,在上傳文件的時候,感覺繞了一圈再回來,一直希望能夠直接把文件直接提交到伺服器上更好,就像我們一般的Web應用上傳附件一樣感覺更好一些,後來發現了可以通過URL.createObjectURL進行相關的處理,參考了一些案例,對前面介紹的JSSDK的圖片上傳方式進行改良,從而實現了把圖片附件通過表單的方式直接提交到自己後臺伺服器上了,下麵開始介紹一下這種方式的思路和實現代碼。

首先我們定義一個預覽圖片的列表和一個Input的文件控制項元素,替代前面的做法,如下所示。

<div class="weui-cells__title">癥狀圖片</div>
<div class="weui-cells weui-cells_form">
    <div class="weui-cell">
        <div class="weui-cell__bd weui-cell_primary">
            <div class="weui-uploader">
                <!--預覽圖片的列表-->
                <ul class="weui-uploader__files" id="imgSick">
                </ul>
                <div class="weui-uploader__input-box">
                    <!--上傳圖片附件控制項-->
                    <input id="uploaderSick" class="weui-uploader__input" type="file" accept="image/*" multiple="">
                </div>
            </div>
        </div>
    </div>
</div>

為了實現選擇圖片文件的時候,預覽圖片的列表可以動態變化(動態增加 li 項目),我們需要定義對應的事件來實現這個操作。

        //存放文件圖片的集合
        var fileSick = new Array();
        var filePres = new Array();
        function initImage() {
            var tmpl = '<li class="weui-uploader__file" style="background-image:url(#url#)"></li>',
            $gallery = $("#gallery"),
            $galleryImg = $("#galleryImg"),

            $uploaderSick = $("#uploaderSick"),
            $imgSick = $("#imgSick"),
            $uploaderPres = $("#uploaderPres"),
            $imgPres = $("#imgPres");

            //癥狀圖片上傳
            $uploaderSick.on("change", function (e) {
                var src, url = window.URL || window.webkitURL || window.mozURL,
                    files = e.target.files;

                for (var i = 0, len = files.length; i < len; ++i) {
                    var file = files[i];
                    fileSick.push(file);//加入集合

                    if (url) {
                        src = url.createObjectURL(file);
                    } else {
                        src = e.target.result;
                    }
                    $imgSick.append($(tmpl.replace('#url#', src)));
                }
            });

          ..............

我們註意到了,這裡沒有使用chooseImage的JSSDK介面,而是通過 url.createObjectURL(file) 的方式獲取路徑,展示在圖片列表控制項裡面。

對於動態增加的圖片,我們可以讓它支持單擊預覽的方式,預覽其實是把圖片放在一個預覽層裡面。

    var index; //第幾張圖片
    var category;//那個類別
    var imgid;//圖片ID
    //癥狀圖片單擊處理
    $imgSick.on("click", "li", function() {
        index = $(this).index();
        category = "sick";
        imgid = $(this).attr("id");
        $galleryImg.attr("style", this.getAttribute("style"));
        $gallery.fadeIn(100);
    });

預覽層的DIV是放在主界面上的,主界面是一個放置圖片的區域,底部是一個刪除按鈕,用來我們實現圖片刪除操作的。

<!--圖片預覽層-->
<div class="weui-gallery" id="gallery">
    <span class="weui-gallery__img" id="galleryImg" style="width:auto"></span>
    <div class="weui-gallery__opr">
        <a href="javascript:" class="weui-gallery__del">
            <i class="weui-icon-delete weui-icon_gallery-delete"></i>
        </a>
    </div>
</div>

預覽層再次單擊的時候關閉,執行的JS代碼如下所示。

$gallery.on("click", function() {
    $gallery.fadeOut(100);
});

刪除圖片的時候,我們區分是存在伺服器的圖片,還是本地臨時選擇的圖片,區別對待。如果伺服器圖片,需要提示確認刪除,如果是本地臨時圖片,直接移除即可。

//刪除圖片(根據類別和序號處理)
$(".weui-gallery__del").click(function () {                
    console.log(index + ',' + category + ',' + imgid);//記錄顯示

    //如果是在服務端的圖片,確認後移除
    if (imgid != undefined && imgid != '') {
        $.confirm("您確定要永久刪除該圖片嗎?", "永久刪除?", function () {
            var url = "/H5/[email protected]";
            var postData = {
                id: imgid.replace(/img_/, '') //控制項id去掉首碼為真正附件ID
            };

            $.post(url, postData, function (json) {
                //轉義JSON為對象
                var data = $.parseJSON(json);
                if (data.Success) {
                    $.toptip("刪除成功!", 'success');

                    //在界面上找到對應控制項ID,移除控制項
                    RemoveImg();
                }
                else {
                    $.toast("操作失敗:" + data.ErrorMessage, "forbidden");
                }
            });
        });
    } else {
        RemoveImg(); //普通圖片快速移除
    };
});

其中移除圖片顯示的JS代碼如下所示。

//移除對應類別的圖片
function RemoveImg() {
    if (category == "sick") {
        $imgSick.find("li").eq(index).remove();
        fileSick.splice(index, 1);
    } else {
        $imgPres.find("li").eq(index).remove();
        filePres.splice(index, 1);
    }
};

我們要使用表單上傳文件的方式,就需要在JS裡面創建一個FormData的對象,用來承載文件內容,如下所示

var formData = new FormData();//構建一個FormData存儲複雜對象

如果是常規的表單數據,我們通過鍵值,把內容填入FormData即可,如下所示。

var formData = new FormData();//構建一個FormData存儲複雜對象
formData.append("PatientName", $("#PatientName").val());

如果是圖片附件的,我們則需要遍歷集合文件,把它們逐一加入對應鍵值裡面,為了區分不同的類別文件,我們使用不同的首碼方式,如下代碼所示。

//加入癥狀圖片
for (var i = 0; i < fileSick.length; i++){
    formData.append("sick_" + i, fileSick[i]);
};
//加入處方圖片
for (var i = 0; i < filePres.length; i++){
    formData.append("pres_" + i, filePres[i]);
};
//提交表單數據和文件            
var url = "/H5/[email protected]";
$.ajax({
    url: url,
    type: 'post',
    processData: false,
    contentType: false,
    data: formData,
    success: function (json) {
        //轉義JSON為對象
        var data = $.parseJSON(json);
        if (data.Success) {
            $.toast("處方已提交審核中,稍後請到處方查詢查看。");
            //WeixinJSBridge.call('closeWindow');//關閉視窗
            location.href = "/h5/Prescription";//跳轉到處方頁面
        }
        else {
            $.toast("保存失敗:" + data.ErrorMessage, "forbidden");
        }
    }
});

 在後臺的處理函數 DrugInquirySave2 裡面,我們需要把文件按鍵名提取出來,根據文件鍵名的不同,放到不同給的集合裡面存儲起來即可。

如下是DrugInquirySave2 函數裡面的部分代碼,用來處理收到的表單文件集合。然後我們在把文件寫入文件系統即可,這樣省卻了對JSSDK提交文件,再去微信伺服器提取文件方式的麻煩,直接由客戶端把文件上傳的自己的文件伺服器了。

#region 通過文件附件方式獲取
var files = Request.Files;
if (files != null && files.Count > 0)
{
    LogTextHelper.Info(string.Format("收到文件:{0}", files.Count));//測試

    foreach (string key in files.Keys)
    {
        LogTextHelper.Info(string.Format("收到文件key:{0}", key));

        var fileData = files[key];
        bool isSickImage = key.ToLower().IndexOf("sick") >= 0;//判斷是否為問診圖片分類
        if (fileData != null)
        {
            HttpContext.Request.ContentEncoding = Encoding.GetEncoding("UTF-8");
            HttpContext.Response.ContentEncoding = Encoding.GetEncoding("UTF-8");
            HttpContext.Response.Charset = "UTF-8";

            string fileName = Path.GetFileName(fileData.FileName);      //原始文件名稱
            string fileExtension = Path.GetExtension(fileName);         //文件擴展名

            FileUploadInfo fileInfo = new FileUploadInfo();
            fileInfo.FileData = ReadFileBytes(fileData);
            if (fileInfo.FileData != null)
            {
                fileInfo.FileSize = fileInfo.FileData.Length;
            }
            //判斷圖片類別分組
            fileInfo.Category = isSickImage ? "問診圖片" : "處方圖片";
            fileInfo.FileName = fileName;
            fileInfo.FileExtend = fileExtension;
            //判斷屬於那個分組【這裡只有兩個分組】
            fileInfo.AttachmentGUID = isSickImage ? SickAttachGUID : PresAttachGUID;

            fileInfo.AddTime = DateTime.Now;//創建時間
            fileInfo.Editor = openid;//記錄人
            fileInfo.Owner_ID = info.ID;//屬於主表記錄

            result = BLLFactory<FileUpload>.Instance.Upload(fileInfo);
            if (!result.Success)
            {
                LogTextHelper.Error("上傳文件失敗:" + result.ErrorMessage);
            }
        }
    }
}
#endregion

編輯現有記錄的時候,也可以實現對已有圖片的刪除操作,臨時文件的預覽處理和再次上傳等操作。

 

3、兩種圖片處理方式的總結

本篇隨筆是基於公眾號上傳圖片文件的兩種方式的處理,分別是使用微信JSSDK和使用URL.createObjectURL上傳預覽圖片的不同處理對比,兩種方式都能夠滿足圖片的處理操作。對比處理代碼,可能使用後者可能更加簡潔一些。而且微信瀏覽器對URL.createObjectURL的支持也非常不錯,可以在微信開發工具和實際環境上都正常使用。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 用途 Clock函數可以有效地針對一些只能用隨機化做的題目 為了提高該類代碼的正確性,我們期望它運行的次數在要求時限內運行足夠多 因此將Clock函數充當計時器 調用 Clock函數所在頭文件ctime/time.h ClOCKS_PER_SEC為常量 時長的計算: 註:begin在程式開頭進行賦值 ...
  • 使用maven搭建Hibernate框架(web項目) 1 create table USERS 2 ( 3 ID NUMBER not null primary key, 4 NAME VARCHAR2(50), 5 PASSWORD VARCHAR2(50), 6 TELEPHONE VARCH ...
  • 公共依賴: 1、創建eureka-server註冊中心工程 a、eureka-server工程pom依賴: b、eureka-server啟動類: c、eureka-server工程配置文件:eureka-server\src\main\resources\bootstrap.yml d、啟動註冊中 ...
  • 2019-10-17-20:21:22 順序結構: 概述:順序執行,根據編寫的順序,從上到下執行語句 判斷語句1-if: if語句第一種格式: if(關係表達式){ 語句體; } 執行流程: 1.首先判斷關係表達式看其結果時true還是false 2.如果是true就執行語句體 3.如果是false ...
  • 如圖所示: C#代碼: lua代碼: ...
  • 昨天在比較完C++中std::vector的兩個方法的性能差異並留下記錄後—— "編程雜談——使用emplace_back取代push_back" ,今日嘗試在C 中測試對應功能的性能。 C 中對應std::vector的數據結構為List。更多的對應關係可以參照下麵: std::vector Li ...
  • 最近公司項目驗收後,客戶請來的信息安全技術人員對我們的網站進行了各種安全測試與排查問題,其中就有一個登陸時的加密問題。本來如果只是單純的加密,可以直接在前臺用MD5加密,將加密的值添加到資料庫即可。但是現在的項目里有很多的用戶,密碼也是後臺MD5加密了的。這樣就不能單純在前臺用MD5加密,可能是本人 ...
  • 1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Reflection; 6 using System.Text; 7 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...