Скачивание и сохранение файлов с сервера с помощью AngularJS

У меня возникла следующая проблема, и я не могу найти решение. Я создал конечную точку с помощью Spring Boot, и когда я использую Postman, я получаю ответ с изображением на запрос тела .

Но когда я пытаюсь загрузить и сохранить файл на компьютере с помощью Angular, Blob и FileSaver, мой сохраненный файл не может быть прочитан.

Это мой угловой контроллер:

vm.download = function (filename) {
    console.log("Start download. File name:", filename);
    $http.get('api/files/download/' + filename)
        .then(function (response) {
            console.log(data);
            var data = new Blob([response.data], {type: 'image/jpeg;charset=UTF-8'});
            FileSaver.saveAs(data, filename);
        })
}

и вот моя конечная точка:

@RequestMapping(value = "/files/download/{id:.*}", method = RequestMethod.GET)
@ResponseBody
@Timed
public void DownloadFiles(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) throws IOException {

    MongoClient mongoClient = new MongoClient();
    DB mongoDB = mongoClient.getDB("angularspingproject");


    BasicDBObject query = new BasicDBObject();
    query.put("filename", id);

    GridFS fileStore = new GridFS(mongoDB, "fs");
    GridFSDBFile gridFSDBFile = fileStore.findOne(query);

    if (gridFSDBFile != null && id.equalsIgnoreCase((String) gridFSDBFile.getFilename())) {
        try {
            response.setContentType(gridFSDBFile.getContentType());
            response.setContentLength((new Long(gridFSDBFile.getLength()).intValue()));
            response.setHeader("content-Disposition", "attachment; filename=" + gridFSDBFile.getFilename());

            IOUtils.copyLarge(gridFSDBFile.getInputStream(), response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("IOError writting file to output stream");
        }
    }
}

Мой заголовок:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 316707
Content-Type: image/jpeg;charset=UTF-8
Pragma: no-cache
Server:Apache-Coyote/1.1
X-Application-Context : angularspingproject:8080
X-Content-Type-Options : nosniff
X-XSS-Protection: 1; mode=block
content-Disposition: attachment; filename=main_page.jpg

@Edit Проблема решена

    vm.download = function (filename) {
        $http.get('api/files/download/' + filename, {responseType:'blob'})
            .then(function (response) {
                console.log(response);
                var data = new Blob([response.data], {type: 'image/jpeg;charset=UTF-8'});
                FileSaver.saveAs(data, filename);
            })
    }

Я добавил responseType: 'blob' в $ http


person Michał Styś    schedule 01.06.2016    source источник
comment
Привет спасибо. Это мне помогло.   -  person Vikas Thakur    schedule 15.03.2018


Ответы (2)


Я предполагаю, что вы не получаете байтовый массив обратно из своего вызова $ http.get. Попробуйте добавить:

vm.download = function (filename) {
var config = {headers: {
        'Accept': "image/jpeg"
    }
};
$http.get('api/files/download/' + filename, config).then(function (response)             { 
       var myBuffer= new Uint8Array( response.data );

    var data = new Blob([myBuffer], {type: 'image/jpeg;charset=UTF-8'});
    FileSaver.saveAs(data, filename);
        })
}
person Mike Feltman    schedule 01.06.2016
comment
К сожалению, это не помогло. - person Michał Styś; 01.06.2016
comment
Я просто изменил это. У меня был png вместо jpeg. Это может быть проблемой. - person Mike Feltman; 01.06.2016
comment
Я только что добавил создание буфера массива. Это то, что Blob ожидает от конструктора. - person Mike Feltman; 01.06.2016

У меня есть специальный сервис загрузки в angular, который работает очень хорошо и просто:

(function () {
    angular.module('common')
        .factory('downloadService', ['$http', '$window', 'contentDispositionParser',
            function ($http, $window, contentDispositionParser) {
                return {
                    downloadFile: downloadFile
                };

                function downloadFile(url, request)
                {
                    $http({
                        url: url, 
                        method: 'GET',
                        params: request,
                        responseType: 'blob'
                    })
                    .success(function (data, status, headers, config){
                        var disposition = headers('Content-Disposition');
                        var filename = contentDispositionParser.getFileName(disposition);
                        $window.saveAs(data, filename); // This is from FileSaver.js
                    });
                }

            }]);
})();

Filesaver.js находится здесь. ContentDispositionParser вы можете использовать что угодно или написать самостоятельно, он используется только для получения правильного имени файла, поскольку это, по-видимому, непростая задача, но она напрямую не связана с сохранением самого файла (вы можете добавить имя в js, например)

person Ilya Chernomordik    schedule 02.06.2016