2015-10-29 17 views
0

在我們的Angular JS應用程序中,我通過簡單地調用window.location來下載文件。防止空白頁上的壞文件下載

HTML:

<div class="row"> 
    <div class="col-md-3 col-sm-4 col-xs-6" ng-repeat="file in files"> 
     <div class="well well-sm truncate"> 
      <a href="" title="Download {{file.FileName}}" ng-click="download(file)" ><b>{{file.FileName}}</b></a><br /> 
      <small>{{(file.FileSize/1024)|number:2}} KB</small><br /> 
      <i class="fa fa-trash CP text-danger pull-right" ng-show="mUser.Role>=20" title="Delete file" ng-click="deletefiles(file.AttID)"></i> 
      <small>Uploaded by <a href="user/{{file.AddedBy}}">{{file.AddedByName}}</a> on {{file.Created|date:'dd MMM yyyy'}}</small> 
     </div> 
    </div> 
</div> 

角方法:

$scope.download = function (ff) { 
    if (confirm('Download this file?')) window.location = "api/files/download?token=" + $rootScope.token + "&IDKey=" + ff.IDKey; 
} 

的Web API控制器的方法:

[HttpGet] 
public HttpResponseMessage download(string Token, string IDKey) 
{ 
    HttpResponseMessage lResponse = new HttpResponseMessage(HttpStatusCode.OK); 

    // Validate request 
    Result lRes = UserClass.GetUserByToken(Token); 
    if (!lRes.IsSuccess) 
    { 
     lResponse.Content = new StringContent("User Token is invalid"); 
     lResponse.StatusCode = HttpStatusCode.Forbidden; 
     return lResponse; 
    } 

    // Get File object 
    AttClass lAtt = AttClass.GetFile(IDKey); 
    if (!lAtt.IsOk) 
    { 
     lResponse.Content = new StringContent("Attachment ID Key is invalid"); 
     lResponse.StatusCode = HttpStatusCode.NotFound; 
     return lResponse; 
    } 

    // Return file 
    lResponse.Content = new StreamContent(new FileStream(lAtt.GetFullPath(), FileMode.Open, FileAccess.Read)); 
    lResponse.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = lAtt.FileName }; 
    lResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
    return lResponse; 
} 

文件下載的作品非常好,當TokenIDKey是有效的。但是,在其他情況下,用戶會看到一個帶有簡單錯誤消息的空白頁面。我能否防止這種情況發生,並在原始頁面上顯示警報,並說明下載失敗的原因?

PS:我做不是想使用HTML5的SaveAs功能或filesaver.js。

回答

1

你可以試試這個

1 - 您是否嘗試過使用iframe的下載文件,而不是使用 window.location的

document.getElementById("myiframe").src="api/files/download?token=" + $rootScope.token + "&IDKey=" + ff.IDKey; 


和檢查的iframe體

document.getElementById('myiframe').contentDocument.body.innerHTML 

重新編輯

document.getElementById("myiframe").src="your url"; 
document.getElementById("myiframe").addEventListener("load", 
function(){ 
console.log(this.contentDocument.contentType); 
if(!(document.getElementById("myiframe").contentDocument.contentType=="application/octet-stream")) 
alert("Downlaod Failed"); 
else 
alert("Thank you for downloading"); 
}); 
+0

下載不起作用時,我會如何通知用戶?服務器的響應可能需要一段時間。 – navigator

+0

document.getElementById(「myiframe」)。src =「your url」; 。 的document.getElementById( 「myiframe」)的addEventListener( 「負載」, 函數(){ 的console.log(this.contentDocument.contentType);! 如果((的document.getElementById(「myiframe 「).contentDocument.contentType ==」application/octet-stream「)) alert(」Downlaod Failed「); else alert(」Thank you for download「); }); –

+0

這只是可能的工作。我會試試看。 – navigator

0

當您使用window.location時,處理服務器響應非常困難。 您可以在angularJs中使用ajax調用進行下載,也可以檢查您的響應。

$http({ url: 'server/url', method: "POST", responseType: 'arraybuffer' }).success(function (data, status, headers, config) { //check your response here

 //smaple code for excel download 
     var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}); 
     var objectUrl = URL.createObjectURL(blob); 
     var anchor = angular.element('<a/>'); 
     anchor.attr({ 
      href: objectUrl, 
      target: '_blank', 
      download: fileName + '_' + new Date().getTime() + '.xlsx' 
     })[0].click(); 
    }).error(function (data, status, headers, config) { 

    }); 

`

+0

感謝。但這正是我想要避免的 - 它看起來更像是一種攻擊,而不是一個強大的解決方案。直到HTML5 SaveAs功能在所有瀏覽器中都能很好地實現,我會盡量避免這種情況。 – navigator