繁体   English   中英

下载文件然后离开页面

[英]download file and then leave page

$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);
});

嗨,我想我做错了什么,我想调用一个函数以向我发送文件作为响应,而后记则想离开页面并转到其他地方。 问题是,因为这是同步,所以我没有下载。

如何使它同步?

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

但是,这里的方法从一开始就有缺陷。 如果浏览器被迫下载文件,则可能会起作用,因为对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'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM