【问题标题】:Decoding a base64 file in Javascript/jQuery for download在 Javascript/jQuery 中解码 base64 文件以供下载
【发布时间】:2012-05-19 19:23:28
【问题描述】:

今天我一直在试验 SQL 二进制对象。我首先将图像存储在表中,发出 AJAX 请求以对图像进行 base64 编码,然后将其显示出来。

<img src="data:image/jpeg;base64,' + base64imageReturnedWithAjax + '">')

图像显示正常。

我正在处理的 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


编辑:如果有帮助,这是从数据库/服务器(在 VB.NET 中)检索和发送文件的网络方法。 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

【问题讨论】:

    标签: jquery sql ajax base64 download


    【解决方案1】:

    内联 base 64 可以很好地处理图像(只要它们很小),所以你可能在正确的轨道上。但是,我不认为您正在为 PDF 或大多数其他 blob(SQL Server 中的varbinary(max))走正确的道路。

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

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

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

    HTTP 处理程序示例

    我将一些生产代码剥离到处理 PDF 的部分。这应该只需最少的修改。

    首先在 Visual Studio 中为您的项目添加一个通用处理程序。它将有一个 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;
            }
        }
    }
    

    要调用此代码,您可以简单地链接到它,例如&lt;a href="RequestHandler.ashx?id=abc"&gt;Download&lt;/a&gt;。您还可以将此代码放在 ASPX 页面中并触发它以响应按钮单击、页面事件等。

    【讨论】:

    • 嗨,蒂姆,所有图像当前都按照您的建议在单个 JSON 对象中提供,很高兴知道这是一种可接受的做法。我将对 HTTP 处理程序和 Response.BinaryWrite() 进行一些阅读,看看我是如何理解的,这些词目前对我来说是陌生的!感谢您的帮助,我给了您一个赞成票,但会等到我读到足够多的内容以确信您是正确的(我几乎肯定您是正确的)之后才给您投票正确的答案!
    • 我一直在努力寻找一个提供 PDF 服务的 HTTP 处理程序的体面示例(我一直这样做)。我能找到的最接近的是stackoverflow.com/questions/10206011/…
    • 从我自己的一个项目中为您添加了一个真实示例。
    【解决方案2】:

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

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

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

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

    但是,我很确定,如果 ajax 请求在响应标头中获得 download 的内容处置,它将冒泡,并且向用户显示下载选项,这将消除对数据架构。

    【讨论】:

      猜你喜欢
      • 2021-04-24
      • 2017-04-07
      • 1970-01-01
      • 1970-01-01
      • 2018-09-19
      • 2020-07-17
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      相关资源
      最近更新 更多