0

我有一个web api从azure中读取文件并将其下载到一个字节数组中。客户端收到该字节数组并将其下载为pdf。这对于大文件不适用。 我无法弄清楚如何从web api发送字节块到客户端。下载大文件时浏览器崩溃

下面是Web API代码仅返回字节数组客户端:

 CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName); 
     blockBlob.FetchAttributes(); 
     byte[] data = new byte[blockBlob.Properties.Length]; 
     blockBlob.DownloadToByteArray(data, 0); 
     return report; 

客户端代码获取数据AJAX请求完成时,创建一个链接,并设置其下载文件的下载属性:

var a = document.createElement("a"); 
a.href = 'data:application/pdf;base64,' + data.$value;; 
a.setAttribute("download", filename); 

1.86 MB的文件发生错误。

浏览器显示消息: 显示网页时出现问题。要继续,请重新加载网页。

+2

使用URL.createObjectURL()代替dataURLs – dandavis

+0

你可以发布你的代码吗?很难看出它的根本问题。什么是错误?它是服务器端错误,客户端错误,你发现文件大小的阈值?我已经完成了从Azure存储下载多个GB文件大小的项目,所以我知道这里没有限制。 – ManOVision

+0

@ManOVision我添加了一些代码。谢谢。 – user2585299

回答

1

问题很可能是您的服务器在这些大文件上的内存不足。不要将整个文件加载到变量中,然后将其作为响应发送出去。这会导致双重下载,您的服务器必须从Azure存储下载并将其保存在内存中,然后您的客户端必须从服务器下载它。你可以做一个流来拷贝,所以内存不会被咀嚼。以下是WebApi控制器的一个示例。

public async Task<HttpResponseMessage> GetPdf() 
{ 
    //normally us a using statement for streams, but if you use one here, the stream will be closed before your client downloads it. 

    Stream stream; 
    try 
    { 
     //container setup earlier in code 

     var blockBlob = container.GetBlockBlobReference(fileName); 

     stream = await blockBlob.OpenReadAsync(); 

     //Set your response as the stream content from Azure Storage 
     response.Content = new StreamContent(stream); 
     response.Content.Headers.ContentLength = stream.Length; 

     //This could change based on your file type 
     response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); 
    } 
    catch (HttpException ex) 
    { 
     //A network error between your server and Azure storage 
     return this.Request.CreateErrorResponse((HttpStatusCode)ex.GetHttpCode(), ex.Message); 
    } 
    catch (StorageException ex) 
    { 
     //An Azure storage exception 
     return this.Request.CreateErrorResponse((HttpStatusCode)ex.RequestInformation.HttpStatusCode, "Error getting the requested file."); 
    } 
    catch (Exception ex) 
    { 
     //catch all exception...log this, but don't bleed the exception to the client 
     return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Bad Request"); 
    } 
    finally 
    { 
     stream = null; 
    } 
} 

我使用(几乎完全)这个代码,并已经能够在尺寸上下载文件超过1GB。

+0

谢谢您的详细解答。该解决方案张贴在http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript也帮助我。谢谢。 – user2585299