利用iframe+from表单实现跨域上传文件

一、需要的材料

客户端需要一个HTML页面A其中包含一个iframe和一个form表单,一个页面B(我称之为客户端代理)里面包含对返回参数的处理;

服务端需要一个asp.net的一般处理程序用来处理上传文件并返回值。

二、原理图

有图才有真相,哈哈哈

三、客户端代码实现

1、页面A的实现

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>A页面</title>
		<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
	</head>

	<body>
		<iframe name='hidden_frame' id="hidden_frame" style='display:none'></iframe>
		<form id="fileform" method="post" enctype="multipart/form-data" target="hidden_frame">
			<input type="file" name="fileUpload" />
		</form>
		<button id="submitbtn">开始上传</button>
		<script type="text/javascript">
			function callback(msg) {
				//回调函数
				alert(msg);
			}
		</script>
		<script type="text/javascript">
			$("#submitbtn").click(function() {
				var callbackurl = window.location.href.substring(0, window.location.href.lastIndexOf('/')) + "proxy.html"; //获取代理文件路径
				$("#fileform").attr("action", "FileHandler.ashx?callbackurl=" + callbackurl);
				$("#fileform").submit();
			})
		</script>
	</body>

</html>

2.代理页面实现 proxy.html 为了方便调用,我将该页面放在了与A页面同一目录下,也可以不同目录,但必须是同域

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>代理文件</title>
	</head>
	<body>
		<script type="text/javascript">
			var rs = window.location.search.split('?').slice(1);
			window.parent.callback(rs.toString().split('=').slice(1));//调用父页面的方法
		</script>
	</body>
</html>

三、服务端实现

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/html";
    HttpServerUtility server = context.Server;
    HttpRequest request = context.Request;
    HttpResponse response = context.Response;
    string callbackurl = context.Request["callbackurl"];
    HttpPostedFile file = context.Request.Files[0];
    if (file.ContentLength > 0)
    {
        string extName = Path.GetExtension(file.FileName);
        string fileName = Guid.NewGuid().ToString();
        string fullName = fileName + extName;
 
        string imageFilter = ".jpg|.png|.gif|.ico";// 随便模拟几个图片类型
        if (imageFilter.Contains(extName.ToLower()))
        {
            string phyFilePath = server.MapPath("~/Upload/Image/") + fullName;
            file.SaveAs(phyFilePath);
            context.Response.Redirect(callbackurl + "?msg='上传成功'")
        }
    }
}

  

四、该方法的优缺点以及适用范围

优点:没有兼容性问题,在常见的浏览器中都是适用的;

缺点:返回数据最大支持2KB,对于较大的数据范围建议使用CORS方式跨域

适用范围:上传文件,返回值只是一些短信息比如返回上传正确与否。

 

转载于:https://www.cnblogs.com/shanligang/p/5789459.html

1、为ScriptManager添加脚本引用,不从ScriptResource.axd中加载MicrosoftAjax.js脚本,而是直接加载 <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"> <Scripts> <asp:ScriptReference Name="MicrosoftAjax.js" ScriptMode="auto" Path="~/ScriptLibrary/System.Web.Extensions/1.0.61025.0/MicrosoftAjax.js" /> </Scripts> </asp:ScriptManager> 2、修改MicrosoftAjax.debug.js 删除 switch(Sys.Browser.agent) { case Sys.Browser.InternetExplorer:与 case Sys.Browser.Safari: 之间的脚本,替换为如下脚本: Sys.UI.DomElement.getLocation = function(element) { if (element.self || element.nodeType === 9) return new Sys.UI.Point(0,0); var clientRect = element.getBoundingClientRect(); if (!clientRect) { return new Sys.UI.Point(0,0); } var ownerDocument = element.document.documentElement; var offsetX = clientRect.left - 2 + ownerDocument.scrollLeft, offsetY = clientRect.top - 2 + ownerDocument.scrollTop; try { var f = element.ownerDocument.parentWindow.frameElement || null; if (f) { var offset = 2 - (f.frameBorder || 1) * 2; offsetX += offset; offsetY += offset; } } catch(ex) { } return new Sys.UI.Point(offsetX, offsetY); } break; 3、修改MicrosoftAjax.js 删除 switch(Sys.Browser.agent){case Sys.Browser.InternetExplorer:与 case Sys.Browser.Safari: 之间的脚本,替换为如下脚本: Sys.UI.DomElement.getLocation=function(a){if(a.self||a.nodeType===9)return new Sys.UI.Point(0,0);var b=a.getBoundingClientRect();if(!b)return new Sys.UI.Point(0,0);var c=a.document.documentElement,d=b.left-2+c.scrollLeft,e=b.top-2+c.scrollTop;try{var g=a.ownerDocument.parentWindow.frameElement||null;if(g){var f=2-(g.frameBorder||1)*2;d+=f;e+=f}}catch(h){}return new Sys.UI.Point(d,e)};break;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值