在Javascript / jQuery中解码base64文件以供下载

今天我一直在试验SQL二进制对象。 我开始将一个图像存储在一个表中,对图像的base64编码进行AJAX请求,然后显示它。

') 

图像显示正常。

我正在处理的Web项目也需要文件下载(主要是PDF) – 很棒,我想,我也将PDF存储为SQL二进制对象,以相同的方式从服务器收集它然后以某种方式神奇地解码它可以在另一端下载。

救命!

我首先尝试使用jQuery base64解码器(https://github.com/carlo/jquery-base64)解码它:

 $.base64.decode(base64fileReturnedWithAjax) 

这会在控制台中生成以下错误:

 Uncaught Cannot decode base64 _getbyte64 _decode $.ajax.success f.Callbacks.o f.Callbacks.p.fireWith w f.support.ajax.f.ajaxTransport.send.d 

因此,我的问题是:这是处理文件下载的可行方法吗? 如果是这样,怎么样! 如果没有,是否有建议的方法允许从SQL表下载文件?

亲切的问候,ATfPT


编辑:如果它有帮助,这是从db / server(在VB.NET中)检索和发送文件的web方法。 Fileblob是数据库中的二进制对象。

  'Having connected to the table While lrd.Read() Dim fileBytes = CType(lrd("Fileblob"), Byte()) Dim stream = New MemoryStream(fileBytes, 0, fileBytes.Length) Dim base64String = Convert.ToBase64String(stream.ToArray()) document.Add(base64String) End While Dim serializer As New JavaScriptSerializer() Dim returnVal As String = serializer.Serialize(document) Return returnVal 

内联基础64适用于图像(只要它们很小),所以你可能在那里正确的轨道。 但是,我不认为你正在沿着正确的路径前往PDF或大多数其他blob(SQL Server中的varbinary(max) )。

我这样做的方法是创建一个HTTP处理程序(Controller,ASHX,ASPX等),它设置正确的HTTP标头,并将从SQL Server检索到的数据作为字节数组传递给Response.BinaryWrite() 。 这是快速,清洁和可靠的。 它还需要很少的代码。

相比之下,base 64编码增加了文件大小,我不知道有任何可靠的方法来处理base 64字符串客户端并指示浏览器使用正确的应用程序打开它。 另外,编码/解码完全是不必要的开销(在大文件上可能很重要)。

顺便提一下,您还可以为图像使用HTTP处理程序。 或者,您可以继续使用base 64,但在单个JSON对象中提供所有图像,这将减少您的请求数量(以更多客户端处理代码为代价)。

HTTP处理程序示例

我将一些生产代码简化为处理PDF的部分。 这应该只需要很少的修改。

首先在Visual Studio中为项目添加Generic Handler。 它将具有ASHX扩展。

 public partial class RequestHandler : IHttpHandler { public void ProcessRequest( HttpContext context ) { HttpRequest request = context.Request; HttpResponse response = context.Response; byte[] bytes = null; // get from your database string fileName = null; // get from database or put something generic here like "file.pdf" response.ContentType = "application/pdf"; response.AddHeader( "content-disposition", "inline;filename=" + fileName ); response.AddHeader( "Content-Length", bytes.Length.ToString() ); response.Buffer = true; response.BinaryWrite( bytes ); response.Flush(); } public bool IsReusable { get { return true; } } } 

要调用此代码,您只需链接到它,例如Download 。 您还可以将此代码放在ASPX页面中并触发它以响应按钮单击,页面事件等。

如果我遵循你的目标,那么问题不在于解码,而在于javascript无法触发下载。 这是因为它无法向浏览器(本身)发送内容处理http标头。

您可以执行以下操作之一(我能想到):

  1. 使用传统的object元素嵌入PDF。 您可以使用jquery动态生成。 并将对象源URL设置为data: URI。

  2. (这只是一个理论),您可以使用window.location.assign('data:xxx ),它可以将用户带到PDF或触发下载,具体取决于处理没有内容处置的PDF的方式。

但是,我很确定,如果一个ajax请求在响应头中获得了download的内容处理,它将会冒出来并向用户提供下载选项,这将消除对数据模式的需求。