ueditor 文件上传的分析和总结
正式开始之前,先写两个常用又容易被我忘掉的文件和流相互转化的方法。
1,文件转流
- FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read);
- byte[] infbytes = new byte[(int)fs.Length];
- fs.Read(infbytes, , infbytes.Length);
- fs.Close();
- return infbytes;
2,流转文件
- FileStream fs = new FileStream("D:\inf.dlv",FileMode.Create,FileAccess.Write);
- fs.Write(infbytes, , inf.Length);
- fs.Close();
目前来说,自己这边网站有两个上传文件(尤其是图片)的方式,一个是通过aspx的文件上传控件直接在pageload里面接受和操作。一个是jquery上传的控件或者用<input type="file">直接上传,我觉得第二中比较具有普遍性,所以最先讨论第二种。
需求:1,接收用户上传的图片。 2,对图片格式和大小有要求。 3,图片需要压缩 。 4,压缩后的图片需要 裁剪,打水印。 5,存到以用户名为名的文件夹下的三个不同的文件夹。 6,以时间戳和随机数命名文件以防止重名。7,接收之后返回新的文件在服务器的相对路径。
第一步:前台页面的代码
有一点需要特别注意,在提交文件的表单中,action="uploadHandler.ashx"这个属性是不能缺少的,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行接下来的操作。(MIME是一种保证非ASCII码文件在internet上传播的规格)
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title></title>
- </head>
- <body>
- <form runat="server" id="form1" method="post" enctype="multipart/form-data" action="uploadHandler.ashx">
- <input name="file" type="file" id="upLoad" />
- <input name="action" type="hidden" value="uploadImage" />
- <input name="s" type="submit" />
- </form>
- </body>
- </html>
隐藏域是用来设置提交方式的,模拟多种提交,比如文件提交,图片提交,批量提交。
第二部,控制器,这里只写了一种配置,就是上传图片的配置
- public void ProcessRequest(HttpContext context)
- {
- Handler action = null;
- switch (context.Request["action"])
- {
- case "uploadimage":
- action = new UploadHandler(context, new UploadConfig()//从配置文件中读取配置
- {
- AllowExtensions = Config.GetStringList("imageAllowFiles"),
- PathFormat = Config.GetString("imagePathFormat"),
- SizeLimit = Config.GetInt("imageMaxSize"),
- UploadFieldName = Config.GetString("imageFieldName"),
- });
- break;
- default:
- break;
- }
- action.Process();
- }
然后是处理类的基类,是一个抽象类,关于抽象类,虚方法,还有比如base调用父类的构造函数这些都属于C#面向对象多态的内容,这个需要重新写一篇东西来总结。
- public abstract class Handler
- {
- public Handler(HttpContext context)
- {
- this.Request = context.Request;
- this.Response = context.Response;
- this.Context = context;
- this.Server = context.Server;
- this.Cookies = context.Request.Cookies;
- }
- /// <summary>
- /// 抽象出来的处理程序,必须被子类重写才能使用
- /// </summary>
- public abstract void Process();
- /// <summary>
- /// 给前台返回结果用的方法,
- /// </summary>
- /// <param name="response"></param>
- protected void WriteJson(object response)
- {
- string jsonpCallback = Request["callback"],
- json = JsonConvert.SerializeObject(response);
- if (String.IsNullOrWhiteSpace(jsonpCallback))
- {
- Response.AddHeader("Content-Type", "text/plain");
- Response.Write(json);
- }
- else
- {
- Response.AddHeader("Content-Type", "application/javascript");
- Response.Write(String.Format("{0}({1});", jsonpCallback, json));
- }
- Response.End();
- }
- public HttpRequest Request { get; private set; }
- public HttpResponse Response { get; private set; }
- public HttpContext Context { get; private set; }
- public HttpServerUtility Server { get; private set; }
- public HttpCookieCollection Cookies { get; set; }
- }
这个是真正的处理类uploadHandler
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using Newtonsoft.Json;
- using System.IO;
- namespace imageTest
- {
- public class UploadHandler : Handler
- {
- //把两个存储类当做本类的属性
- public UploadConfig UploadConfig { get; private set; }
- public UploadResult Result { get; private set; }
- /// <summary>
- /// 在派生类中访问基类的构造函数
- /// </summary>
- /// <param name="context"></param>
- /// <param name="config"></param>
- public UploadHandler(HttpContext context, UploadConfig config)
- : base(context)
- {
- this.UploadConfig = config;
- this.Result = new UploadResult() { State = UploadState.Unknown };
- }
- /// <summary>
- /// 正式的重写这个处理程序
- /// </summary>
- public override void Process()
- {
- byte[] uploadFileBytes = null;
- string uploadFileName = null;
- HttpPostedFile file = Request.Files[UploadConfig.UploadFieldName];
- uploadFileName = file.FileName;
- if (!CheckFileType(uploadFileName))
- {
- Result.State = UploadState.TypeNotAllow;
- WriteResult();
- return;
- }
- if (!CheckFileSize(file.ContentLength))
- {
- Result.State = UploadState.SizeLimitExceed;
- WriteResult();
- return;
- }
- //在所有的判断都结束之后,正式的对文件进行处理,这个没写
- }
- private void WriteResult()
- {
- this.WriteJson(new
- {
- state = GetStateMessage(Result.State),
- url = Result.Url,
- title = Result.OriginFileName,
- original = Result.OriginFileName,
- error = Result.ErrorMessage
- });
- }
- private string GetStateMessage(UploadState state)
- {
- switch (state)
- {
- case UploadState.Success:
- return "SUCCESS";
- case UploadState.FileAccessError:
- return "文件访问出错,请检查写入权限";
- case UploadState.SizeLimitExceed:
- return "文件大小超出服务器限制";
- case UploadState.TypeNotAllow:
- return "不允许的文件格式";
- case UploadState.NetworkError:
- return "网络错误";
- }
- return "未知错误";
- }
- private bool CheckFileSize(int size)
- {
- return size < UploadConfig.SizeLimit;
- }
- private bool CheckFileType(string filename)
- {
- var fileExtension = Path.GetExtension(filename).ToLower();
- return UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
- }
- }
- /// <summary>
- /// 上传配置对象,主要是用来读取后存放配置数据
- /// </summary>
- public class UploadConfig
- {
- /// <summary>
- /// 文件命名规则
- /// </summary>
- public string PathFormat { get; set; }
- /// <summary>
- /// 上传表单域名称
- /// </summary>
- public string UploadFieldName { get; set; }
- /// <summary>
- /// 上传大小限制
- /// </summary>
- public int SizeLimit { get; set; }
- /// <summary>
- /// 上传允许的文件格式
- /// </summary>
- public string[] AllowExtensions { get; set; }
- /// <summary>
- /// 文件是否以 Base64 的形式上传
- /// </summary>
- public bool Base64 { get; set; }
- /// <summary>
- /// Base64 字符串所表示的文件名
- /// </summary>
- public string Base64Filename { get; set; }
- /// <summary>
- /// 用户的用户名
- /// </summary>
- public string UserName { get; set; }
- public string WaterUrl { get;set;}
- public string SmallUrl { get; set; }
- public string
- }
- /// <summary>
- /// 上传结果对象,主要是用来存储程序的处理结果
- /// </summary>
- public class UploadResult
- {
- public UploadState State { get; set; }
- public string Url { get; set; }
- public string OriginFileName { get; set; }
- public string ErrorMessage { get; set; }
- }
- /// <summary>
- /// 枚举类型,程序的处理结果.
- /// </summary>
- ///
- public enum UploadState
- {
- Success = ,
- SizeLimitExceed = -,
- TypeNotAllow = -,
- FileAccessError = -,
- NetworkError = -,
- Unknown = ,
- }
- }
总结一下人家的设计思路,editor最先通过自己的js的配置文件初始化编辑器并且找到路径来访问control.ashx一般处理程序,ashx通过http访问的表单的action来判断是哪种操作,是上传文件还是图片还是读取等等,然后通过这个action,去config.json里面来读取具体的关于文件上传和下载等等配置,把这些配置通过配置对象加上httpcontext上下文一起传到文件上传控制类uploadHandler,uploadHandler继承自handler,所以构造函数可以调用基类的,process方法也是重写基类的抽象方法。
ueditor 文件上传的分析和总结的更多相关文章
- Java Web文件上传原理分析(不借助开源fileupload上传jar包)
Java Web文件上传原理分析(不借助开源fileupload上传jar包) 博客分类: Java Web 最近在面试IBM时,面试官突然问到:如果让你自己实现一个文件上传,你的代码要如何写,不 ...
- 1.5 webshell文件上传漏洞分析溯源(1~4)
webshell文件上传漏洞分析溯源(第一题) 我们先来看基础页面: 先上传1.php ----> ,好吧意料之中 上传1.png ----> 我们查看页面元素 -----> ...
- UEditor编辑器两个版本任意文件上传漏洞分析
0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...
- [转]UEditor编辑器两个版本任意文件上传漏洞分析
0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...
- 【代码审计】UKCMS_v1.1.0 文件上传漏洞分析
0x00 环境准备 ukcms官网:https://www.ukcms.com/ 程序源码下载:http://down.ukcms.com/down.php?v=1.1.0 测试网站首页: 0x0 ...
- 【代码审计】XYHCMS V3.5文件上传漏洞分析
0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...
- 【代码审计】JTBC(CMS)_PHP_v3.0 任意文件上传漏洞分析
0x00 环境准备 JTBC(CMS)官网:http://www.jtbc.cn 网站源码版本:JTBC_CMS_PHP(3.0) 企业版 程序源码下载:http://download.jtbc. ...
- 【代码审计】QYKCMS_v4.3.2 任意文件上传漏洞分析
0x00 环境准备 QYKCMS官网:http://www.qykcms.com/ 网站源码版本:QYKCMS_v4.3.2(企业站主题) 程序源码下载:http://bbs.qingyunke. ...
- 【代码审计】BootCMS v1.1.3 文件上传漏洞分析
0x00 环境准备 BootCMS官网:http://www.kilofox.net 网站源码版本:BootCMS v1.1.3 发布日期:2016年10月17日 程序源码下载:http://w ...
随机推荐
- Parallel.For 你可能忽视的一个非常实用的重载方法
说起Parallel.For大家都不会陌生,很简单,不就是一个提供并行功能的for循环吗? 或许大家平时使用到的差不多就是其中最简单的那个重载方法,而真实情况 下Parallel.For里面有14个重 ...
- 【iOS】7.4 定位服务->2.1.3.3 定位 - 官方框架CoreLocation 功能3:区域监听
本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...
- python学习之路-书籍推荐
学python有一段时间了,总结走来的路,发现还是看书靠谱,当然也要多实践. 一.入门篇 1.简明 Python 教程(A Byte of python) http://www.kuqin.com/a ...
- ThinkPHP3.2.3版本验证码异步第二次验证时失败的问题解决
最近在用TP3.2.3做一个小项目,纠结于验证码验证问题,重点在于二次验证,举个例子就是常见的登录页面上有个验证码输入框,当用户输入验证码并且鼠标点击在这个输入框之外时候,触发onblur事件,然后a ...
- 获取JVM的dump文件
获取JVM的dump文件的两种方式 1. JVM启动时增加两个参数: #出现 OOME 时生成堆 dump: -XX:+HeapDumpOnOutOfMemoryError #生成堆文件地址: -XX ...
- Java排序算法之直接选择排序
Java排序算法之直接选择排序 基本过程:假设一序列为R[0]~R[n-1],第一次用R[0]和R[1]~R[n-1]相比较,若小于R[0],则交换至R[0]位置上.第二次从R[1]~R[n-1]中选 ...
- 实践 config drive - 每天5分钟玩转 OpenStack(170)
如果 instance 无法通过 metadata service 获取 metadata(无 DHCP 或者 nova-api-metadata 服务),instance 还可以通过 config ...
- Web前端面试指导(十四):如何居中一个元素(正常、绝对定位、浮动元素)?
题目点评 这道题目的提问比较多,连续问了三个问题,正常元素.绝对定位元素.互动元素如何居中,而且居中没有说清楚是垂直居中还是水平居中,要回答清楚这个问题,必须得有深厚的功底,而且要分类的来回答,条理要 ...
- 浅谈C10K问题
在大型的APP中进行高并发的访问,淘宝,支付宝,微信,QQ,等 C10K问题:高并发的进行访问 C10K问题的最大特点是:设计不够良好的程序,其性能和连接数及机器性能的关系往往 是非线性的.举个例子: ...
- Realm数据持久化方案的简单介绍和使用(二)
接上篇... 4. 可空属性&默认值&忽略属性 默认情况下, 属性值可空, 如果强制要求某个属性非空, 可以使用如下方法: 遵循协议方法 + (NSArray *)requiredPr ...