使用 JavaScript 下载文件






4.39/5 (11投票s)
一篇关于如何使用 JavaScript 下载文件的文章。

引言
我知道很多开发者像我一样也在寻找这种解决方案。 我有同样的需求,即使用 JavaScript 从服务器下载文件,而无需回发整个页面。 它的优点在于,它可以在 IE/Firefox/Chrome 浏览器中工作。 我没有使用 ScriptManager/UpdatePanel 任何东西,而是使用了 Handler 和普通的 JavaScript 代码。 Handler 用于将响应写回页面。 我记录了您可能在编程中使用的步骤。 我不能在 Firefox 中使用 ActiveXObject 创建 Excel 对象,因为 ActiveXObject 在 Firefox 中不起作用。
我是如何做到的?
- 在页面上添加 span 标签,它将作为链接工作
- 创建 FileHandler.ashx 以将响应写回页面。
public void ProcessRequest(HttpContext context) { fileName = HttpUtility.UrlDecode(context.Request.Params["fileName"]); string FullFilePath = context.Server.MapPath("~/Common/Files/" + fileName); FileInfo file = new FileInfo(FullFilePath); if (file.Exists) { context.Response.ContentType = MIMETypeUtility.MIMETypeDescription(MIMEType.Excel); context.Response.AddHeader ("Content-Disposition", "attachment; filename=\"" + file.Name + "\""); context.Response.AddHeader("Content-Length", file.Length.ToString()); context.Response.WriteFile(file.FullName); context.Response.End(); } }
您可以根据需要使用任何 MIME 类型。 我展示了一些您可以在应用程序中使用的 MIME 类型。 有关更多 MIME 类型,请参阅 http://msdn.microsoft.com/en-us/library/ms775147%28VS.85%29.aspx
public enum MIMEType { [DescriptionAttribute("text/HTML")]TextHTML, [DescriptionAttribute("image/GIF")]Gif, [DescriptionAttribute("image/JPEG")]JPEG, [DescriptionAttribute("text/plain")]TextPlain, [DescriptionAttribute("Application/msword")]Word, [DescriptionAttribute("Application/vnd.ms-excel")]Excel, [DescriptionAttribute("Application/vnd.xls")]FirefoxExcel } public class MIMETypeUtility { public static string MIMETypeDescription(Enum mimeType) { FieldInfo fi = mimeType.GetType().GetField(mimeType.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes (typeof(DescriptionAttribute), false); if (attributes.Length > 0) { return attributes[0].Description; } else { return mimeType.ToString(); } } }
- 创建 FileHandler.js 文件来完成主要工作。 它将动态创建一个 iframe,其宽度、高度和边框均为 0。 然后创建一个表单标签,其中包含一个输入控件,用于在提交 iframe 时传递文件名(例如 ExcelFile.xls)。
var createFrame = function() { var frame = document.createElement("iframe"); frame.name = "fileFrame"; frame.id = "fileFrame"; document.body.appendChild(frame); generateIFrameContent(); frame.style.width = "0px"; frame.style.height = "0px"; frame.style.border = "0px"; }
GetExcelFile
函数会将 Excel 文件名作为参数传递,并提交一个 iframe 窗口,handler 将运行代码并将文件响应写回页面,用户将获得打开/保存/取消对话框。var getExcelFile = function() { var frmWindow = getIFrameWindow(); var fileName = frmWindow.document.getElementById("fileName"); fileName.value = encodeURI("ExcelFile.xls"); var frm = frmWindow.document.getElementById("frmFile"); frm.submit(); }
- 创建 LoadScript.aspx 页面以将脚本添加到页面响应。 您可以在此处添加任意数量的脚本,我更喜欢这种方式,这样可以在运行时隐藏 JavaScript 和脚本文件的位置。
private void loadScript() { List<string> scripts = new List<string>(); scripts.Add(Server.MapPath("~/Common/JS/FileHandler.js")); try { bool isStyles = this.GetType().BaseType.Name == "Styles"; this.Response.Clear(); this.Response.ContentType = isStyles ? "text/css" : "text/javascript"; byte[] data = null; try { StringBuilder sb = new StringBuilder(); foreach (string str in scripts) sb.Append(File.ReadAllText(str)); data = new ASCIIEncoding().GetBytes(sb.ToString()); } catch (Exception ex) { throw ex; } this.Response.AddHeader("Content-Length", data.LongLength.ToString()); this.Response.BinaryWrite(data); this.Response.End(); } catch (Exception ex) { throw ex; } }
- 将以下代码添加到 FileHandler.aspx 页面以加载脚本并使用初始化 JavaScript 函数的启动脚本。
protected void Page_Load(object sender, EventArgs e) { Type type = this.GetType(); if (!this.ClientScript.IsClientScriptIncludeRegistered(type, "scrScripts")) this.ClientScript.RegisterClientScriptInclude (type, "scrScripts", "Common/Loaders/LoadScripts.aspx"); if (!this.ClientScript.IsStartupScriptRegistered(type, "scrHandlerStartUp")) this.ClientScript.RegisterStartupScript (type, "scrHandlerStartUp", GetStartUpScript(), true); } private string GetStartUpScript() { return "try{{var handler = new FileHandler();handler.init();}}catch(e) {{document.getElementById('divNotLoaded').style.display = '';}}"; }
结论
您可以使用 AJAX(Scriptmanager
+ Updatepanel
)从服务器下载文件,但您必须回发页面。 这种技术对页面来说是轻量级的。 我的项目需求是从数据库中获取数据,创建一个 Excel 文件,插入数据并将文件下载到用户机器。 并且我的整个网站都在使用 AJAX(JS+WebServices
并且没有 updatepanel
),在这种情况下我不能使用任何服务器控件,因为那将会回发我的整个页面,而我不想让这种情况发生。 因此,经过大量的研发和许多方法,这是我使用的一种技术,并且它在生产环境中运行成功。 如果您有任何问题,请通过 phani.nadigadda@gmail.com 与我联系。
历史
- 2010 年 1 月 29 日:初始版本