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