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代码
ashx源代码
原创文章,转载请注明出处: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('没有远程图片需要上传!');
, 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";
default: return 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;
}
}
}
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";
default: return 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();
}
///
/// 下载网络图片
///
/// 图片网络地址
/// 保存到本地图片的时间文件夹
/// 第几个文件
/// 上下文对象
///
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编辑器远程图片自动上传