$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 :(得分:0)
Async与它无关。一旦你进入成功回调,异步部分就已经完成了。问题是您在第一次更改有时间加载之前再次更改窗口位置。换句话说,它与异步问题完全相反;问题是这段代码是同步的,运行得太快。
然而,这里的方法有缺陷。如果浏览器被迫下载文件,可能工作,因为第一次更改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,然后从PDF数据中创建一个对象URL。然后,您可以使用它在DOM中创建一个锚元素,并动态“单击”它以提示下载。但需要注意的是,我没有尝试过使用Angular,所以我不确定$http
是否支持获取二进制响应。我知道使用jQuery,你只需告诉它XHR对象的响应类型是'blob',但我不确定你是否可以或如何使用Angular做同样的事情。作为替代方案,您只需将XMLHttpRequest
直接用于此特定AJAX,只需设置xhr.responseType = 'blob'
。