web编辑器远程图片自动上传

  有些时候在使用web编辑器编辑文章的时候,如果有图片,而又不希望从别人的服务器下载图片,这是如果图片比较多,那么一张张保存后重新上传到服务器就会很麻烦。而且有些时候别人的图片是通过动态页面加载,加了防盗链时,粘贴到自己的网站就会显示防盗链的图片。
  今天自己鼓捣了下,弄了一个远程图片自动上传到服务器的ajax+ashx下载远程图片的程序,发现即使是加了防盗链的动态页面加载的图片也能下载原图下来【QQ空间的测试通过,其他的暂时不知道】,省心了很多。
  原理如下
  1)ajax方面:用document.getElementsByTagName获取到img标签,然后判断src是否为远程图片,如果是则搜集图片的url地址,并且保存这些远程图片的img对象到一个数组中,用ajax发送这些远程地址到服务器的动态页,然后处理完毕后返回本地的图片路径,方便更新img的src为自己服务器的url地址。
  2)动态页方面,使用C#的ashx文件下载图片。考虑到了防盗链的动态页加载图片的问题,所以不能通过判断url的后缀是否为图片文件这种方法,也就不好使用webclient直接下载文件。而是使用httpwebrequest来请求图片url【包括防盗链的地址】,然后通过httpwebresponse的ContentType来或者实际图片文件的后缀。

  实现代码如下,可能和实际的应用有些差别,在使用时自己修改下。
  ajax+js代码
+展开
-JavaScript
  var imgs =document.getElementById('ifrEditor').contentWindow.document.getElementsByTagName('img')//这里注意修改为你自己的web编辑器的ID
      , upimgs = []//收集远程图片对象img的数组,方便更新src属性
      , url = []//收集远程图片地址的数组
      , rx = new RegExp('^https?:\\/\\/' + location.host.replace(/\./g, '\\.'), 'i')//本站主域名的正则
      , rxRemote = /^https?:\/\// //远程图片正则
      , xhr, src;
      for (var i = 0; i < imgs.length; i++) {
        src = imgs[i].src;
        if (!rx.test(src) && rxRemote.test(src)) { url[url.length] = src; upimgs[upimgs.length] = imgs[i]; }//收集远程图片地址和img对象
      }
      //获取图片的父对象是否为链接,是则返回以便同时更新链接url
      function getParantA(obj) { while (obj = obj.parentNode) if (obj.tagName == 'A'return obj; return false; }
      if (url.length > 0) {//存在远程图片
        xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('microsoft.xmlhttp');
        xhr.open('POST''remotefiles.ashx'true);//==============这里注意修改ajax请求的页面
        xhr.setRequestHeader('content-type''application/x-www-form-urlencoded');
        xhr.send('files=' + encodeURIComponent(url.join('|')));//发送远程图片路径
        xhr.onreadystatechange = function () {
          if (xhr.readyState == 4) {
            var r = 200 == xhr.status ? eval('(' + xhr.responseText + ')') : { success: false, err: 404 == xhr.status ? '请求的页面找不到!' : '发生错误,请稍后再试!' };
            if (r.success) {//注意ashx返回的items数组对象一定要和发送时的upimgs数组的长度一致
              var pNode;
              for (var i = 0; i < r.items.length; i++)
                if (r.items[i]) {
                  upimgs[i].src = '/imgblog/' + r.items[i];
                  pNode = getParantA(upimgs[i]);//========看图片是否加了链接,加了同时更新链接的href
                  if (pNode) pNode.href = '/imgblog/' + r.items[i];
                }
            }
            else alert(r.err);
          }
        }
      }
      else alert('没有远程图片需要上传!');


ashx源代码
+展开
-C#
<%@?WebHandler?Language="C#"?Class="remotefiles"?%>

using System;
using System.Web;
using System.IO;
using System.Net;
public class remotefiles : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
    /// 
    /// 通过mime类型获取图片后缀
    /// 

    /// mime类型
    /// 图片后缀
    private string GetExt(string MIME)
    {
        switch (MIME.ToLower().Trim())
        {
            case "image/gif"return "gif";
            case "image/jpeg"return "jpg";
            case "image/png"return "png";
            case "application/x-ms-bmp":
            case "image/nbmp"return "bmp";
            defaultreturn null;
        }
    }
    /// 
    /// 将下载的文件流写入硬盘
    /// 

    /// 本地文件的路径
    /// 文件流
    private void WriteToHDD(string FullPath,Stream ns)
    {
        FileStream writer = new FileStream(FullPath, FileMode.OpenOrCreate, FileAccess.Write);
        int bufferSize = 512, readSize = 0;
        byte[] buffer = new byte[bufferSize];
        readSize = ns.Read(buffer, 0, bufferSize);
        while (readSize > 0)
        {
            writer.Write(buffer, 0, readSize);
            readSize = ns.Read(buffer, 0, bufferSize);
        }
        writer.Flush();
        writer.Close(); 
    }
    /// 
    /// 下载网络图片
    /// 

    /// 图片网络地址
    /// 保存到本地图片的时间文件夹
    /// 第几个文件
    /// 上下文对象
    /// 如果是图片则下载并返回生成的文件名,否则返回null
    private string DownLoadFile(string url,string folder,int i,HttpContext context)
    {
        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
        HttpWebResponse response = (HttpWebResponse)req.GetResponse();
        string ext = GetExt(response.ContentType)/*根据响应头获取后缀*/, fileName = null;
        if (ext != null)//是图片文件
        {
            fileName = DateTime.Now.ToString("yyyyMMddHHmmss")+ i.ToString() + "." + ext;
            Stream ns = response.GetResponseStream();
            WriteToHDD(context.Server.MapPath("~/imgblog/" + folder + "/" + fileName), ns);//注意修改保存图片的路径
            ns.Close();
        }
        response.Close();
        return fileName;
    }
    public void ProcessRequest(HttpContext context)
    {
            string js = "";
            string files = context.Request.Form["files"];
            if (string.IsNullOrEmpty(files)) js = "{success:false,err:'没有远程图片需要上传!'}";
            else
            {
                string[] arrFiles = files.Split('|');
                string func = context.Request.QueryString["func"], folder = DateTime.Now.ToString("yyyyMMdd")
                    , fns = context.Session["fns"as string, fileName = "";
                if (!Directory.Exists(context.Server.MapPath("~/imgblog/" + folder)))
                    Directory.CreateDirectory(context.Server.MapPath("~/imgblog/" + folder));
                for (int i = 0; i < arrFiles.Length; i++)
                {
                    try
                    {
                        fileName = DownLoadFile(arrFiles[i], folder, i, context);
                        if (fileName == null) js += ",false";
                        else
                        {
                            if (fns == null) fns = folder + "/" + fileName;
                            else fns += "," + folder + "/" + fileName;
                            js += ",'" + folder + "/" + fileName + "'";
                        }
                    }
                    catch { js += ",false"; }
                }
                if (fns != null) context.Session["fns"] = fns;//保存下载的图片的路径到session中,以便存储到文章的表中,这样在删除文章的时候知道要同时删除那些图片
                js = "{success:true,items:[" + js.Trim(',') + "]}";
            }
            context.Response.Charset = "utf-8";
            context.Response.Write(js);
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}

加支付宝好友偷能量挖...


原创文章,转载请注明出处:web编辑器远程图片自动上传

评论(0)Web开发网
阅读(259)喜欢(0)Asp.Net/C#/WCF