ueditor上传图片到七牛(CSharp版本)

ueditor是百度推出的一款文本编辑器,其内部提供了图片上传的逻辑,可以把本地的图片上传到网站服务器。但是包括本人在内的很多草根站长可能会选择把图片放到其它一些CDN服务器上去,以便节约自己服务器的流量压力。

本人选择的是七牛云存储,因为它提供免费的图片存储服务,且支持外链、图片处理等高级的功能(貌似阿里云也正在推出类似的服务)。


好了,编辑器和图片存储都有了,现在问题是如何把两者结合起来,能否使用ueditor将图片直接上传到七牛,除此之外,在使用ueditor进行图片管理的时候能够直接显示七牛上的图片。带着问题去问度娘和谷哥,找到了一位朋友写的ueditor上传图片到七牛云存储(form api,java),根据这篇文章的方法,基于C#语言,我也同样成功实现了预期的功能。




准备工作

下载 ueditor, 我使用的是1.3.6 .Net utf-8 版本。

下载 七牛 C# SDK

因为我用的是VS 2012, 所以新建一个类型为“Asp.net MVC4 Web应用程序”的项目,然后将ueditor和七牛加入到解决方案中。


配置七牛

新建空间

登录七牛后,选择新建空间(记住在七牛中空间的代名词是bucket,后面我们会用到),勾选“公开空间”。然后进行空间配置,可以看到七牛为我们提供了很多有用的功能,诸如域名设置、防盗链、镜像存储等。


在七牛里新建空间


域名设置[可选]

我们现在只要关注域名设置。你可以使用七牛提供的二级域名也可以使用自己站点的域名。指定自己的域名后,记住在你的DNS服务商中加入一个cname记录,指向你七牛中的二级域名。


在七牛里进行域名设置


设置cname


数据处理[可选]

七牛云存储内建了一个非常高效易用的数据处理框架。数据处理框架可以管理和执行一系列符合规范的数据处理操作(fop)。开发者可以在访问资源时制定执行一个或多个数据处理指令,以直接获取经过处理后的结果。

比较典型的一个场景是图片查看。客户端可以上传一张高精度的图片,然后在查看图片的时候根据屏幕规格生成一张大小适宜的缩略图,比如为iPhone生成一张960x640大小的缩略图。这样既可以明显降低网络流量,而且可以提高图片显示速度,还能降低移动设备的内存占用。

新建一个名叫“small.jpg”的数据操作,提供对图片进行缩放(宽或高最大500像素)同时添加水印的能力。

例,原图地址为 http://img.chenxu.me/demo.gif,  那么进行数据处理后的图片地址就变成  http://img.chenxu.me/demo.gif-small.jpg。


在七牛里新增数据处理


jpg后缀,并不代表当前的图片是jpg格式。你完全可以取类似“abc.d.z.x”这种名称


配置ueditor

1. 修改 ueditor.config.js 中的图片上传区


        //图片上传配置区
        , imageUrl: "http://up.qiniu.com/"             //图片上传提交地址        
        , imagePath: "http://img.chenxu.me/"           //图片修正地址,引用了fixedImagePath,如有特殊需求,可自行配置        
        , imageFieldName: "file"                       //图片数据的key,若此处修改,需要在后台对应文件修改对应参数        
        //,compressSide:0                              //等比压缩的基准,确定maxImageSideLength参数的参照对象。0为按照最长边,1为按照宽度,2为按照高度        
        ,maxImageSideLength:1600                       //上传图片最大允许的边长,超过会自动等比缩放,不缩放就设置一个比较大的值,更多设置在image.html中


imageUrl的地址修改为七牛的上传地址。imagePath中则修改为上一节中你设立的域名。imageFiledName用于指定上传的文件类型,这里要改为“file”,同时在image.html中对应的地方也需要修改(后面会讲到)。maxImageSideLength 修改成你所允许上传的最大边长,默认为900,如果你的图片尺寸大于这个尺寸,那么在上传到七牛之前ueditor已经把图片等比缩放成900的边长,图片就失真了。



2. 修改 ueditor.config.js 中的图片管理区


        //图片在线管理配置区        
        , imageManagerUrl: URL + "net/imageManager.ashx"       //图片在线管理的处理地址        
        , imageManagerPath: "http://img.chenxu.me/"            //图片修正地址,同imagePath


把imageManagerPath的地址修改为你在七牛中的域名。



3. 修改 dialogs\image\image.html


因为我们在上传的时候需要向七牛传递一个token值,所以先在html中增加一个隐藏的input元素用来保存我们的token值。


 <div id="local" class="panel">               
      <div id="flashContainer"></div>                    
      <div><div id="upload" style="display: none" ></div><div id="duiqi"></div><div id="localFloat"></div></div>
      <div class="saveDir">                   
           <var id="lang_savePath" ></var><span id="saveDirSelector"><var id="lang_load_savePath"></var></span>                    
      </div>                    
      <input id="qiniu_token" type="hidden" name="token" />  <!-- 新增一个隐藏域 -->               
 </div>


为了能够使用jquery功能,请在image.html中增加一句对jquery的引用。然后修改如下代码。


  //=========新增代码===================
  $.ajax({
      url: "http://"+location.host + "/Home/QiniuUploadToken",
      type: "get"        
  }).done(function (data) {
      $("#qiniu_token").val(data);
  });
  //====================================

  editor.setOpt({
      imageFieldName:"file", //修改成file
      compressSide:0,
      maxImageSideLength:900
  });


用ajax调用我们ASP.Net MVC的接口,将得到的值填充到我们的隐藏域。 imageFieldName则修改成与ueditor.config.js中一样的“file”。至于QiniuUploadToken,后面会介绍。


修改完后,接着向下找到对 initSavePath 方法的调用,并注释掉。否则在运行过程中,它会发起对http://up.qiniu.com/?fetch=1的get操作,而这是不被允许的,七牛会返回405错误。

 //initSavePath();


接着再向下找到如下代码,并进行修改。


 $G("upload").onclick = function () {

      //===========注释掉下面的语句,否则就会直接结束,而无法上传=============
      //if ( !savePathComplete ) {
      //    alert('请等待保存目录就绪!')
      //    return;
      //}
      
      /**
       * 接口imageUploader.setPostParams()可以在提交时设置本次上传提交的参数(包括所有图片)
       * 参数为json对象{"key1":"value1","key2":"value2"},其中key即为向后台post提交的name,value即为值。
       * 其中有一个特殊的保留key值为action,若设置,可以更改本次提交的处理地址
       */                
       var postParams = {
           //===========注释掉下面的语句,已经用不上了=============              
           //"dir": baidu.g("savePath").value,  
                             
          "token": $("#qiniu_token").val()   //增加token参数
      };
      imageUploader.setPostParams(postParams);
      flashObj.upload();
      this.style.display = "none";
      //$G("savePath").parentNode.style.display = "none"; 同时注释掉,否则会报null中不包含parentNode之类的错误信息
 };


因为新的逻辑中已经不需要savePathComplete,而这个变量则可能会因为我们没有配置对ueditor所需要的上传路径而一直保持“false”,反而影响我们的逻辑执行,所以可以直接注释掉。然后,在postParams中要加入一个新的参数“token”,这个值需要传给七牛服务器。


配置解决方案

打开解决方案管理器,通过添加现有项目对话框,把之前我们准备好的七牛sdk中的Qiniu文件夹中的Qiniu.4.0.csproj直接加入到解决方案中。

找到其中的Conf\Config.cs。修改其中的 Init 方法,将该方法修改成静态构造函数,以便该方法能在首次构造时执行。


  static Config()
  {
      USER_AGENT = System.Configuration.ConfigurationManager.AppSettings["USER_AGENT"];
      ACCESS_KEY = System.Configuration.ConfigurationManager.AppSettings["ACCESS_KEY"];
      SECRET_KEY = System.Configuration.ConfigurationManager.AppSettings["SECRET_KEY"];
      RS_HOST = System.Configuration.ConfigurationManager.AppSettings["RS_HOST"];
      UP_HOST = System.Configuration.ConfigurationManager.AppSettings["UP_HOST"];
      RSF_HOST = System.Configuration.ConfigurationManager.AppSettings["RSF_HOST"];
      PREFETCH_HOST = System.Configuration.ConfigurationManager.AppSettings["PREFETCH_HOST"];
  }


配置 Asp.net MVC 项目

在web.config中加入下列节点,用于暗示你在七牛中的配置,其中的 access_key 和 secret_key 请更换成你对应的值。该值可以在七牛的后台看到,进入后台后,不要选择任何一个空间,直接点击账号设置,选择左边的密钥。


在七牛里查看AccessKey和SecretKey


  <appSettings>
      <add key="webpages:Enabled" value="false" />
      <!--for qiniu upload-->    
      <add key="USER_AGENT" value="qiniu csharp-sdk v6.0.0" />    
      <add key="ACCESS_KEY" value="填写你在七牛中看到的access key" />    
      <add key="SECRET_KEY" value="填写你在七牛中看到的secret key" />    
      <add key="RS_HOST" value="http://rs.Qbox.me" />    
      <add key="UP_HOST" value="http://up.qiniu.com" />    
      <add key="RSF_HOST" value="http://rsf.Qbox.me" />    
      <add key="PREFETCH_HOST" value="http://iovip.qbox.me" />  
  </appSettings>

注意要写在最外侧的web.config中,不然实际运行中无法读取相关节点


增加对我们新引进的Qiniu项目的引用。

接着,修改HomeController,增加两个新action。


  //==================for 七牛 ==================================
  
  public ContentResult QiniuUploadToken()
  {
      var policy = new PutPolicy("chenxublog");
      policy.ReturnUrl = "http://localhost:1407/home/QiniuUploadCallBack";
      policy.ReturnBody = "{\"name\": $(fname),\"size\": \"$(fsize)\",\"w\": \"$(imageInfo.width)\",\"h\": \"$(imageInfo.height)\",\"key\":$(etag)}";
      string token = policy.Token();
      return Content(token);
  }

  public JsonResult QiniuUploadCallBack()
  {
      string ret = Request.QueryString["upload_ret"];
      dynamic data = System.Web.Helpers.Json.Decode(DecodeFromBase64("UTF-8", ret));
   
      return Json(new { original = data["name"], w = data["w"], h = data["h"], url = data["key"], state = "SUCCESS" }, JsonRequestBehavior.AllowGet); 
  }

  private string DecodeFromBase64(string encode,string code)
  {
      string decode = "";
      byte[] bytes = Convert.FromBase64String(code);
      try            {
          decode = Encoding.GetEncoding(encode).GetString(bytes);
      }
      catch            {
          decode = code;
      }
      return decode;
  }

  //==============================================================


修改Home/index.cshtml,增加对ueditor的初始化语句


<script src="~/ueditor/ueditor.config.js"></script>
<script src="~/ueditor/ueditor.all.min.js"></script>
<script src="~/ueditor/lang/zh-cn/zh-cn.js"></script>
<script id="editor" type="text/plain" style="width:1024px;height:500px;"></script>
<script type="text/javascript">
     //实例化编辑器    
     //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例    
     UE.getEditor('editor'); 
</script>


经过上述步骤,你已经实现了使用ueditor上传到七牛的功能。现在可以运行Asp.net MVC项目来试验下了。


尝试使用ueditor上传到七牛


修改imageManager.ashx

接下来,实现如何使用ueditor来进行图片管理。用下列代码替换原先的代码。


    public void ProcessRequest(HttpContext context)
    {
        RSFClient client = new RSFClient("chenxublog"); //这里填写最先申请的空间名称
        var picColl = client.ListPrefix("chenxublog", "", ""); //取得空间内的所有图片
 
        StringBuilder sb = new StringBuilder();
 
        //对图片按照时间先后进行排序后输出
        foreach (var pic in (from x in picColl.Items orderby x.PutTime descending select x)) 
        {
            if (pic.Key.Length > 0)
            {
                sb.AppendFormat("/{0}-small.jpg{1}", pic.Key, "ue_separate_ue"); //加上-small.jpg,这样ueditor中得到的就是处理后的图片            }
        }
 
        sb.Length -= "ue_separate_ue".Length;
        context.Response.ContentType = "text/plain";
        context.Response.Write(sb.ToString());
    }


OK,大功告成。现在可以用ueditor来实现图片上传和管理了。


使用ueditor按时间顺序显示七牛中的图片


源代码管理

QiniuAndUeditor


参考资料

  1.  C# SDK 使用指南

  2. ueditor上传图片到七牛云存储

文章索引

[隐 藏]

本站采用知识共享署名 3.0 中国大陆许可协议进行许可。 ©2014 Charley Box | 关于本站 | 浙ICP备13014059号