利用LRZ压缩与Base64编码实现高效文件上传

在这里插入图片描述

引言

在当今互联网时代,文件上传已成为众多在线服务不可或缺的一部分,尤其是在社交媒体平台上的照片分享和云存储服务中的文档管理等场景,高效且安全的文件上传机制对于保障用户体验至关重要。
为此,本文将介绍一种结合了LRZ压缩工具与Base64编码技术的优化文件上传方案。通过使用LRZ压缩工具对文件进行预处理,可以有效减小文件大小,进而提高上传效率并减少带宽消耗;而采用Base64编码则能够确保数据在网络传输过程中的完整性和安全性,从而为用户提供更加流畅和安全的文件上传体验。此方案特别适用于需要上传个人资料或头像等图片文件的应用场景。

使用LRZ上传

LRZ是一种高效的文件压缩工具,它支持多种压缩算法,能够在保持高压缩比的同时快速完成文件的压缩与解压操作。LRZ特别适用于大量小文件的压缩场景,因为它的性能优越,可以显著减少文件体积,加快网络传输速度。

Base64编码

在某些特定情况下,如通过电子邮件或HTTP请求发送二进制数据时,直接传输可能会遇到兼容性问题。此时,将文件转换为Base64格式可以有效解决这一问题。Base64编码将二进制数据转换为ASCII字符串,使得数据可以在任何传输介质上安全传输。

什么是Base64编码

定义

Base64是一种基于64个可打印字符来表示二进制数据的编码方式。它主要用于在网络上传输二进制数据,因为许多网络传输协议都是文本协议。这些字符包括A-Z、a-z、0-9以及两个额外的符号(通常是“+”和“/”)。每3个字节的二进制数据会被编码为4个Base64字符,因此Base64编码后的数据量会增加约33%。例如,100KB的二进制数据经过Base64编码后会变成约133KB。

工作原理

  1. 分组:将原始二进制数据按每3个字节一组进行分组。
  2. 转换:每个3字节的二进制数据被转换为4个6位的数值。
  3. 映射:每个6位的数值被映射到Base64编码表中的相应字符。
  4. 填充:如果最后一组不足3个字节,则使用“=”字符进行填充。

优缺点

  • 安全性:Base64编码不是加密方法,只是将二进制数据转换为文本数据,容易被解码。
  • 局限性:由于增加了数据量,不适合传输大量数据。
  • 优点:兼容性强,适用于多种传输协议;便于调试和日志记录。
  • 缺点:数据量增加,传输效率降低;编码和解码过程需要额外计算资源。

目的和应用场景

  • 目的:确保二进制数据在网络传输过程中不会被破坏。
  • 应用场景:电子邮件附件、网页中的图片嵌入、API请求中的二进制数据传输等。

上传功能的逻辑和代码

在这里插入图片描述
在这里插入图片描述

整体设计思路

  1. 用户选择图片文件。
  2. 使用lrz库对图片进行压缩。
  3. 将压缩后的图片转换为Base64格式。
  4. 通过AJAX将Base64字符串发送到服务器。
  5. 服务器接收到Base64字符串,解码并保存图片。
  6. 返回图片的URL给前端。

示例代码

前端代码

<asp:Content ID="Content3" ContentPlaceHolderID="ScripttPlaceHolder2" runat="server"><!-- 引入LRZ压缩库 --><script src="lib/lrz/dist/lrz.bundle.js" type="text/javascript"></script><!-- 引入jQuery库 --><script src="Scripts/jquery-3.7.0.min.js" type="text/javascript"></script><script>// 当文件输入框发生变化时触发事件$$("#upload").on("change", function () {// 使用LRZ库对选中的文件进行压缩,设置压缩后的宽度和高度为300像素lrz(this.files[0], { width: 300, height: 300 }).then(function (rst) {// 异步上传压缩后的图片$.post("ashx/UploadAvatar.ashx", { len: rst.base64Len, baseString: encodeURI(rst.base64) },function (res) {// 如果上传成功if (res.State == 1) {// 将上传成功的图片路径存储到隐藏控件中,用于后续更新使用$("#hfAvatar").val(res.Message);// 创建一个新的Image对象var image = new Image();// 设置图片的源路径image.src = res.Message;// 设置图片的宽度和高度image.width = 100;image.height = 100;// 将图片添加到父元素中$("#uploadselect").parent().append(image);// 移除原来的上传按钮$("#uploadselect").remove();} else {// 如果上传失败,弹出提示alert("上传失败");}}, "json");});});</script>
</asp:Content>
前端代码
  1. 引入LRZ压缩库和jQuery库

    • lrz.bundle.js:用于图片压缩。
    • jquery-3.7.0.min.js:用于DOM操作和AJAX请求。
  2. 文件输入框变化事件

    • 使用$$("#upload").on("change", function () { ... })监听文件输入框的变化。
    • 使用lrz(this.files[0], { width: 300, height: 300 })对选中的文件进行压缩,设置压缩后的宽度和高度为300像素。
  3. 异步上传

    • 使用$.post方法发送AJAX请求,将压缩后的Base64字符串和长度发送到服务器。
    • 如果上传成功,将返回的图片路径存储到隐藏控件中,并创建一个新的Image对象显示图片。
    • 如果上传失败,弹出提示。

后端代码

using HPIT.Model;
using Newtonsoft.Json;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;namespace HPITAixiu.ashx
{/// <summary>/// 处理头像上传的一般处理程序/// </summary>public class UploadAvatar : IHttpHandler{public void ProcessRequest(HttpContext context){context.Response.ContentType = "text/plain";// 从请求中获取Base64字符串的长度int len = int.Parse(context.Request.Form["len"]);// 如果长度小于等于0,返回400错误状态码if (len <= 0){context.Response.StatusCode = 400;context.Response.End();return;}// 从请求中获取Base64字符串的长度int base64Length = context.Request.Form["baseString"].Length;// 如果Base64字符串长度小于等于0,返回400错误状态码if (base64Length <= 0){context.Response.StatusCode = 400;context.Response.End();return;}// 将前台传过来的Base64格式的文件进行解码,存储到字节数组中// 注意:这里使用了HttpUtility.UrlDecode来解码URL编码的Base64字符串byte[] bytes = new byte[HttpUtility.UrlDecode(context.Request.Form["baseString"]).Length];// 如果压缩没有问题,传输到服务器上的文件长度和压缩的文件长度应相等if (len == bytes.Length){// 获取Base64字符串中实际的图像数据部分,去掉前缀(如"data:image/jpeg;base64,")var baseString = context.Request.Form["baseString"].Split(',')[1];// 将Base64编码的字符串转换成字节数据byte[] newType = Convert.FromBase64String(baseString);// 生成一个随机文件名,避免上传的名字相同被覆盖string randomString = Guid.NewGuid().ToString();// 设置上传路径string filePath = $"{context.Server.MapPath("~/avatar/")}{randomString}.jpg";// 定义一个用于返回图片上传成功的路径string imageUrl = $"/avatar/{randomString}.jpg";// 将文件在内存流中进行传输using (MemoryStream memoryStream = new MemoryStream(newType)){// 从内存流中将图片读取出来using (Image image = Image.FromStream(memoryStream)){// 将读取出来的图片存储到指定的路径下image.Save(filePath, ImageFormat.Jpeg);}}// 创建一个AjaxResult对象,用于返回上传结果AjaxResult ajaxResult = new AjaxResult{State = 1, // 表示上传成功Message = imageUrl // 上传成功的图片路径};// 将当前返回的Ajax结果进行JSON序列化并响应到前台context.Response.Write(JsonConvert.SerializeObject(ajaxResult));}else{// 如果文件长度不匹配,返回400错误状态码context.Response.StatusCode = 400;context.Response.End();}}}
}
后端代码
  1. 设置响应内容类型

    • context.Response.ContentType = "text/plain":设置响应的内容类型为纯文本。
  2. 获取Base64字符串的长度

    • int len = int.Parse(context.Request.Form["len"]):从请求中获取Base64字符串的长度。
    • 如果长度小于等于0,返回400错误状态码。
  3. 获取Base64字符串

    • string baseString = context.Request.Form["baseString"]:从请求中获取Base64字符串。
    • 如果Base64字符串为空,返回400错误状态码。
  4. 解码Base64字符串

    • byte[] bytes = Convert.FromBase64String(baseString.Split(',')[1]):解码Base64字符串,去掉前缀(如"data:image/jpeg;base64,")。
  5. 生成随机文件名

    • string randomString = Guid.NewGuid().ToString():生成一个随机文件名,避免文件名冲突。
    • string filePath = context.Server.MapPath($"~/avatar/{randomString}.jpg"):设置上传路径。
  6. 保存图片

    • 使用MemoryStream将文件在内存流中进行传输。
    • 使用Image.FromStream(memoryStream)从内存流中读取图片。
    • 使用image.Save(filePath, ImageFormat.Jpeg)将图片保存到指定路径。
  7. 返回上传结果

    • 创建一个AjaxResult对象,用于返回上传结果。
    • 使用JsonConvert.SerializeObject(ajaxResult)将结果进行JSON序列化并响应到前台。
  8. 是否可重用

    • public bool IsReusable { get { return false; } }:表示该处理程序是否可以重用。

总结

通过本文,我们详细介绍了如何使用LRZ压缩工具上传图片,并结合Base64编码进行处理。这种方式不仅提高了文件传输的效率,还确保了数据的完整性和兼容性。希望本文能对您有所帮助,鼓励您尝试并在实际项目中应用这些技术。

参考资料

  • LRZ官方文档
  • Base64编码详解
  • jQuery官方文档
  • C#官方文档

希望这篇博客文章能够帮助您更好地理解和应用LRZ压缩和Base64编码技术。如果有任何问题或需要进一步的帮助,请随时联系我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146359.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

使用vite+react+ts+Ant Design开发后台管理项目(三)

前言 本文将引导开发者从零基础开始&#xff0c;运用、react、react-router、react-redux、Ant Design、less、tailwindcss、axios等前沿技术栈&#xff0c;构建一个高效、响应式的后台管理系统。通过详细的步骤和实践指导&#xff0c;文章旨在为开发者揭示如何利用这些技术工具…

VSCode环境下连接 MySQL 8.0 数据库 (C++)

前言 时隔了不知道多久&#xff0c;笔者需要在Windows环境下通过VSCode重新搭建一个简单的数据库连接的Cpp工程。由于VSCode和MySQL的版本和之前连通时发生了一些变化&#xff0c;无需用MySQL Connector&#xff0c;环境配置的细节和之前也不尽相同&#xff0c;因此笔者找了一…

简单有效关于msvcp140.dll丢失的解决方法,msvcp140.dll修复的方法原理及步骤

这篇文章将和大家分享几种msvcp140.dll丢失的解决方法&#xff0c;分析解决方法为什么能够通过这种方法进行修复成功&#xff0c;有效的将丢失的msvcp140.dll文件进行修复完成。 msvcp140.dll丢失&#xff1f;简单有效的解决途径 一、重新安装相关软件 原理 许多应用程序在安…

掌握Android开发新趋势:Jetpack与现代架构技术全解析

随着Android开发技术的不断进步&#xff0c;Jetpack和现代架构技术已成为构建高效、可维护应用的关键。本文将为您介绍一套全面的学习资料&#xff0c;包括大纲、PDF文档、源代码以及学习视频&#xff0c;帮助您深入理解Jetpack核心库、架构组件以及现代开发工具。 内容&#…

【C++】—— string模拟实现

前言&#xff1a; 学习了string的使用&#xff0c;总感觉了解不是很深厚&#xff1b;自己模拟实现string类来帮助自己理解。 这里只是实现了一部分内容&#xff08;并没有实现完整的string类&#xff09;。 先来实现string类里面的成员变量&#xff1a; #include<iostream…

草莓团队创造了o1 - Building OpenAI o1 (Extended Cut) 观后笔记

美妙的事物往往需要世界去创造&#xff0c;商业希望大模型越来越快给出回答。或许花费几个月几年的时间持续思考&#xff0c;大模型能够解决更复杂的问题&#xff0c;而不只是回答42 刚发现凌晨OpenAI发布了一个22多分钟的采访&#xff0c;将构建出O1的整个团队拉到一个小屋子&…

让Tkinter更美观:教你同步Tkinter窗口与弹窗图标(Tkinter同步主窗口与Messagebox的图标)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 步骤1:主窗口图标📝 步骤2:messagebox 图标📝 示例代码📝 实现原理与代码解释⚓️ 相关链接 ⚓️📖 介绍 📖 你有没有注意到,在开发软件图形界面时,会需要弹出一些提示框,而这些提示框的图标总…

695. 岛屿的最大面积

思路&#xff1a; 只有当前是陆地&#xff0c;才会构成岛屿 当前是陆地&#xff0c;进入回溯 往当前的上、下、左、右位置分别找陆地位置&#xff0c;为陆地 1>标记为2:代表已经遍历过的陆地 2>记录当前方向的陆地总数 以当前陆地组成的岛屿面积当前陆地面积向上的…

11----mtk芯片专用解锁工具 解除FRP 很小的工具 去除屏幕锁 免授权等等 工具预览与步骤解析

机型的FRP锁是谷歌账号锁。工具是mtk芯片使用 。可以去除当前机型的FRP和米账号重置。操作非常简单。但前提是联机驱动要装好。任何的工具联机驱动是关键。 工具功能选项 ★★★★★工具开发者说明功能与选项操作与资源下载 ★★★★★具体工具操作使用指南 工具联机界面与…

Type-C协议(CC检测原理)-CC1和CC2接电阻-数字和模拟耳机兼容

Type-C协议&#xff08;CC检测原理&#xff09;-CC1和CC2接电阻-数字和模拟耳机兼容 - Sean_hn - 博客园 (cnblogs.com)

4.变量与函数

作业系统链接 变量是Python中用于存储数据的命名标签&#xff0c;通过赋值&#xff0c;新值可以覆盖旧值&#xff0c;且数据类型不必相同。变量命名规则包括必须以字母或下划线开头&#xff0c;由字母、数字和下划线组成&#xff0c;大小写敏感&#xff0c;并避免使用保留字。函…

精选写作技巧!分享4款ai写毕业论文可以写出公式表格的软件

在撰写毕业论文时&#xff0c;AI写作工具可以极大地提高效率和质量。以下是四款值得推荐的AI软件&#xff0c;它们不仅能够帮助生成高质量的论文初稿&#xff0c;还能处理公式和表格等复杂内容。 传送门&#xff1a;https://www.aipaperpass.com?piclLGw 千笔-AIPassPaper是一…

Rx Strategist:智能体实现处方验证的方方面面,如适应症、剂量、药物相互作用

Rx Strategist&#xff1a;智能体实现处方验证的方方面面&#xff0c;如适应症、剂量、药物相互作用 秒懂大纲提出背景&#xff1a;拆解解法分析全流程分析创意 秒懂大纲 ├── 处方验证系统【主题】 │ ├── 背景和问题【问题描述】 │ │ ├── 现代药物复杂性对严…

2024年华为杯研究生数学建模竞赛研赛C题超详细解题思路+数据预处理代码分享

研赛题目由当年负责赛区【23年为东南大学&#xff0c;24年为山东大学】的相关老师每年独立命题&#xff0c;因此每年的题目在涉及的模型和知识点上都有很大差异。数模竞赛是百分比获奖&#xff0c;选择人数最多的也就意味着题目简单&#xff0c;会有很多新手、小白选择。我们只…

python有main函数吗

python和C/Java不一样&#xff0c;没有主函数一说&#xff0c;也就是说python语句执行不是从所谓的主函数main开始的。 当运行单个python文件时&#xff0c;如运行a.py&#xff0c;这个时候a的一个属性__name__是__main__。 当调用某个python文件时&#xff0c;如b.py调用a.p…

华为HarmonyOS地图服务 13 - 如何实现地图数据聚合效果?

场景介绍 本章节将向您介绍如何根据地图数据实现聚合效果。 您可以通过比例尺缩放自适应聚合效果,聚合图标可点击。聚合支持功能: 支持按距离聚合ClusterItem。支持绘制聚合Overlay的默认图标。支持绘制聚合Overlay的自定义图标。支持监听聚合Overlay的点击事件。支持添加单…

华为为什么要做三折叠屏手机?

前些天我做了一条视频&#xff0c;关于讲华W的新的三折叠屏手机。我说我有点失望&#xff0c;结果引起了华W的同事的一些关注。于是&#xff0c;华W几位高管都跑过来&#xff0c;跟我解释为什么会出现这样的一个状态。 我才知道&#xff0c;这款手机他们其实是亏着钱在卖的。因…

云盘视频保护神器,支持云盘视频加密与在线播放,配合alist使用,超完美!

平时我们保护视频&#xff0c;一般都是采用压缩工具&#xff0c;进行加密打包&#xff0c;然后在上传到网盘存储。这虽然能起到很好的保护&#xff0c;但是有很多问题&#xff1f;比如&#xff1a;无法直接在线播放&#xff0c;还得从网盘中下载后解压&#xff0c;才能进行观看…

【shell脚本1】Shell脚本学习--入门

目录 简介 Hello World 注释 打印输出 简介 Shell是一种脚本语言&#xff0c;那么&#xff0c;就必须有解释器来执行这些脚本。 Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等&#xff0c;习惯上把它们称作一种Shell。我们常说有多少种Shell&#xff0c;其实说的…

ProtoBuf序列化框架介绍

文章目录 ProtoBuf介绍使用流程 QUICK START创建.proto文件注释语法编译部分代码展示使用接口运行结果 ProtoBuf介绍 ProtoBuf全称是Protocol Buffer&#xff0c;是一个数据结构的序列化和反序列化框架 他又很多好处&#xff0c;首先是他支持跨平台&#xff0c;支持Java、C、…