ueditor 文件上传的分析和总结

正式开始之前,先写两个常用又容易被我忘掉的文件和流相互转化的方法。

1,文件转流

FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read);
byte[] infbytes = new byte[(int)fs.Length];
fs.Read(infbytes, 0, infbytes.Length);
fs.Close();
return infbytes;

2,流转文件

FileStream fs = new FileStream("D:\inf.dlv",FileMode.Create,FileAccess.Write);
fs.Write(infbytes, 0, 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 = 0,
        SizeLimitExceed = -1,
        TypeNotAllow = -2,
        FileAccessError = -3,
        NetworkError = -4,
        Unknown = 1,
    }
}

总结一下人家的设计思路,editor最先通过自己的js的配置文件初始化编辑器并且找到路径来访问control.ashx一般处理程序,ashx通过http访问的表单的action来判断是哪种操作,是上传文件还是图片还是读取等等,然后通过这个action,去config.json里面来读取具体的关于文件上传和下载等等配置,把这些配置通过配置对象加上httpcontext上下文一起传到文件上传控制类uploadHandler,uploadHandler继承自handler,所以构造函数可以调用基类的,process方法也是重写基类的抽象方法。

时间: 2025-01-13 11:29:38

ueditor 文件上传的分析和总结的相关文章

1.5 webshell文件上传漏洞分析溯源(1~4)

webshell文件上传漏洞分析溯源(第一题) 我们先来看基础页面: 先上传1.php ---->   ,好吧意料之中 上传1.png  ---->   我们查看页面元素 ----->   ,也没有前端验证 看来只能用burp抓包来改包绕过,我们修改1.php  ---->   1.php .png ,然后上传抓包改包 0x20 -----> 0x00 webshell文件上传漏洞分析溯源(第一题) 我们先来看基础页面: 先上传1.php ---->   ,好吧意料之中

分布式文件系统 fastdfs 源码分析 之 文件上传流程分析

fastdfs是一个轻量级的分布式文件系统,主要由 tracker server, storage server 以及client组成,这里主要涉及两点 : 1)客户端上传文件流程和协议分析 2)实现一个简单的文件上传函数 一: 文件上传的基本流程 fastdfs中上传一个文件,主要涉及以下几个步骤: 1)上传连接请求,客户端会向tracker server发出上传文件的请求 2)tracker收到请求后,返回storage server的ip和端口 3)客户端连接storage,并且上传文件

Ueditor文件上传问题

我们在做一些网站是会遇到,要有上传文件一类的事情. 我发现百度的富文本编辑器带上传功能,但是没有办法给后台传递我们要的参数. 先在ueditor.all.js中找到, me.execCommand('insertHtml', html); 在它下面添加: me.fireEvent('afterUpfile',filelist); 此时,我们就可以在前台监听上传了. ps:filelist你联系上文,我们可以知道就是我们要的文件信息数组,有后台返回的. 在前台添加,uploadEditor为编辑器

将Ueditor文件上传至OSS

前人已经将ueditor集成了oss,本次是作为记录 1:点击到下载页面 下载并按照文档安装 2:将 com.zip(在UEditor-for-aliyun-OSS-master\ueditor\src\main\java)拷贝到你的src下 3: 安装原作者文档配置OSSKey.properties,注意:源文档少了ossCliendEndPoint,加上即可,具体如下: 1 # default value false 2 useStatus=true 3 4 # ALIYUN OSS buc

Android Day05-网络编程之文件上传

Android文件上传实现 分析:利用抓包工具查看文件上传发现,文件上传的请求体十分的复杂,根本难以用 HttpURLConnection.HttpClient来实现.但是用AsyncHttpClient就能很轻易的实现了,只要 在RequestParams对象里面添加一对键值对,值存储文件的路径即可上传了. AsyncHttpClient文件上传源代码:

php 文件上传缩略图路径分析类

<?php //文件上传时分析路径信息 //author:songzhenghe 2014-1-24 //version 0.1 class path_ana {     private $data_root;     private $web_root;     private $http_domain;     private $file;     private $r;          public function __construct(){         //从配置文件中读取  

Struts2之struts2文件上传详解

一.学习案例:通过在uploadfile.jsp页面填写完表单,提交后跳转到success.jsp页面,然后验证upload包下上传文件是否成功. 二.案例分析:struts2文件上传并不是表面上看的只需简单配置就可以上传文件.实际是分为两步的.1.struts2首先将客户端上传的文件保存到struts.multipart.saveDir键所指定的目录,如果该键所对应的目录不存在,就会保存到javax.servlet.context.tempdir环境变量所指定的目录中.2.Action中所定义

TCP实现文件上传

文件上传分析 一.基本实现 1.服务端 public class FileUpload_Server { public static void main(String[] args) throws IOException { System.out.println("服务器 启动..... "); // 1. 创建服务端ServerSocket ServerSocket serverSocket = new ServerSocket(8888); // 2. 建立连接 Socket ac

网站漏洞修复之UEditor漏洞 任意文件上传漏洞 2018 .net新

UEditor于近日被曝出高危漏洞,包括目前官方UEditor 1.4.3.3 最新版本,都受到此漏洞的影响,ueditor是百度官方技术团队开发的一套前端编辑器,可以上传图片,写文字,支持自定义的html编写,移动端以及电脑端都可以无缝对接,自适应页面,图片也可以自动适应当前的上传路径与页面比例大小,一些视频文件的上传,开源,高效,稳定,安全,一直深受站长们的喜欢. 百度的UEditor文本编辑器,近几年很少被曝出漏洞,事情没有绝对的,总会有漏洞,这次被曝出的漏洞是.net版本的,其他的php