使用Angular.js - 如何从需要身份验证的后端提供二进制数据?

jhn*_*wsk 3 javascript rest http http-headers angularjs

在我的angularjs应用程序中,我正在与后端服务器通信,后端服务器需要通过http头进行基本访问身份验证.我已经描述实现对客户端的认证机制在这里.

angular.module('myAuthModule')
.config(['$httpProvider', '$stateProvider',
    function ($httpProvider, $stateProvider) {
        $httpProvider.interceptors.push('securityInterceptor');
    }])
.factory('securityInterceptor', ['$location', '$window', '$q',
    function ($location, $window, $q) {
        return {
            request: function (config) {
                config.headers = config.headers || {};
                if ($window.sessionStorage.token) {
                    config.headers['Auth-Key'] = $window.sessionStorage.token;
                }
                return config;
            },
            response: function (response) {
                if (response.status === 401 || response.status === 403) {
                    $location.path('/login');
                }
                return response || $q.when(response);
            }
        };
    }
]);
Run Code Online (Sandbox Code Playgroud)

到目前为止一切顺利,在角度应用程序中处理xhr请求按预期工作.

问题是我需要提供pdf文档的下载链接.我的后端服务器有一个/Document/Pdf/:id资源,用于application/pdf响应ContentDisposition: attachment,还需要进行身份验证.我知道我无法使用xhr启动下载,但是它们都提供了文档下载链接,ngHref并调用了一个功能,例如$window.open('/Document/Pdf/13')导致401 Unauthorized服务器响应.

我在这里错过了什么?

jhn*_*wsk 6

探讨了@Geoff Genz给出的可能性,添加了第四个 - data-uri选项,遗憾的是不允许定义文件名 - 我决定采用不同的方法.

我在API中添加了一个方法,该方法根据正常验证的请求生成一次性下载链接并立即下载.角度处理程序变得非常简单

.factory('fileFactory', ['$http', '$window',
    function ($http, $window) {
        return {
            downloadFile: function (fileId) {
                return $http(
                    {
                        method: "POST",
                        data: fileId,
                        url: '/api/Files/RequestDownloadLink',
                        cache: false
                    }).success(function (response) {
                        var url = '/api/File/' + response.downloadId;
                        $window.location = url;
                    });
            }
        };
    }]);
Run Code Online (Sandbox Code Playgroud)

这不是完美的,但我觉得最不好看.这也适用于我,因为我可以完全控制前端和后端.