2017-03-08 62 views
0
$http.post('@Url.Action("donePressed")', 
{ 
    id: $scope.id, 
}).then(
function (response) // success callback 
{ 
    window.location = '@Url.Action("PdfCreator", "someController")?Id=' + $scope.id; 
    window.location='@Url.Action("Index","AnotherController")'; 
}, 
function (response) // failure callback 
{ 
    alert(response.statusText); 
}); 

您好,我想我做的服用点错了,我想打电话给函数的向我发送文件作为响应,和后记我要离开这个页面,去别的地方。 问题是,因为这是同步我没有得到我的下载。下载文件,然后离开页面

如何使此同步?

回答

0

异步与它无关。一旦进入成功回调,异步部分已经完成。问题在于,在第一次更改有时间加载之前,您要再次更改窗口位置。换句话说,这与异步问题完全相反;问题是这段代码是同步的,运行速度太快。

但是,这里的方法是有缺陷的。它可能工作,如果浏览器被迫下载文件,因为那么第一次更改为window.location本身不会导致浏览器视图更改。由于PDF通常是浏览器可浏览的类型,但这并不能保证。无论如何,你仍然有同样的问题需要延迟第二个电话,直到第一个电话得到响应,这基本上是不可能的。这种类型的事情没有内置的事件,所以最好你可以做的就是使用setTimeout延迟1-2秒,只是希望这是足够的时间来获得第一个响应。即使这样,如果它花费更长时间,您的代码也会再次中断。换句话说,它会变得非常脆弱。

简单的事实是,这仅仅不是HTTP的工作方式。你基本上试图为单个请求返回两个响应,这是不可能的。这是一种巧妙的方式,可以避开协议中固有的限制,我会给你的,但最终还是不够。

所有这一切说,你可以实际上使通过HTML5文件API和AJAX这种情况发生,但你的解决方案,然后将只与现代浏览器兼容(基本上一切,除了IE 10和下)。如果你不需要支持较低版本的IE,那么你可以使用下面的代码来代替:

function (response) // success callback 
{ 
    $http.get('@Url.Action("PdfCreator", "someController")?Id=' + $scope.id').then(
     function (response) // success callback 
     { 
      var a = document.createElement('a'); 
      var url = window.URL.createObjectURL(response.data); 
      a.href = url; 
      a.download = 'myfile.pdf'; 
      a.click(); 
      window.URL.revokeObjectURL(url); 
      window.location = '@Url.Action("Index","AnotherController")'; 
     }, 
     function (response) // failure callback 
     { 
      alert(response.statusText); 
     } 
    ); 
}, 

的秘诀是在获取通过AJAX的PDF,然后创建一个对象URL出来的PDF数据。然后,您可以使用它在DOM中创建一个锚点元素并动态“点击”它以提示下载。但是,需要注意的是,我还没有尝试过使用Angular,所以我不确定$http是否支持获取二进制响应。我知道jQuery,你只需告诉它,XHR对象的响应类型是'blob',但我不确定你是否可以或如何使用Angular做同样的事情。作为替代,您可以直接使用XMLHttpRequest直接用于此特定AJAX,并且只需设置xhr.responseType = 'blob'即可。

相关问题