Попытка отправить почтовый индекс от серверной части к веб-интерфейсу - PullRequest
0 голосов
/ 19 февраля 2019

В какой-то момент в моем ember.js веб-приложении пользователю предоставляется возможность загрузить zip-файл.При нажатии на кнопку запускается действие, которое отправляет запрос на внутренний сервер, который генерирует zip и возвращает его.В идеале zip должен быть загружен автоматически.

В моей конечной точке бэкэнда я возвращаюсь с

return Response
        .ok(FileUtils.readFileToByteArray(new File(tmpZipFilename))) // tmpZipFilename is a String
        .type("application/zip")
        .header("Content-Disposition", "attachment; filename=\"" + finalZipFilename + "\"")
        .build();

В моем внешнем интерфейсе (адаптировано с здесь )

submit() {
  var formData = new FormData(this);
  let token = this.get('session.data.authenticated.token');
  jquery.ajax({
    url: `myUrl`,
    data: formData,
    processData: false,
    contentType: false,
    beforeSend: function(xhr) {xhr.setRequestHeader('Authorization', `Bearer ${token}`)},
    type: 'POST',
    success: function(data) {
      var blob = new Blob([data], {type: 'application/zip'});
      let a = document.createElement("a");
      a.style = "display: none";
      document.body.appendChild(a);
      let url = window.URL.createObjectURL(blob);
      a.href = url;
      a.download = 'myFile.zip';
      a.click();
      window.URL.revokeObjectURL(url);
    },
    failure: function() {
      // other stuff
    }
  })
}

Заголовки ответа следующие:

HTTP/1.1 200 OK
X-Powered-By: Undertow/1
Cache-Control: no-store
Date: Tue, 19 Feb 2019 16:34:35 GMT
Server: WildFly/10
Content-Type: application/zip
Content-Disposition: attachment; filename="filename.zip"
Connection: close
Transfer-Encoding: chunked

Я подтвердил, что tmpZipFilename в разделе бэкэнда правильно указывает на правильный zip-файл.И когда пользователь нажимает кнопку загрузки, файл с именем myFile.zip действительно загружается.Однако загружаемый файл не может быть распакован и имеет размер, отличный от правильного файла, на который указывает tmpZipFilename.Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

На самом деле для загрузки файлов лучше всего просто позвонить window.open.

0 голосов
/ 21 февраля 2019

Если ваш API возвращает реальный файл, и у вас правильно заданы тип и расположение контента, вы можете просто создать естественную ссылку во внешнем интерфейсе на конечную точку API или использовать стандартную форму, а не AJAX-запрос, так какзагрузка файла начнется, и вы останетесь на том же месте, что и вдова.

Для первого варианта:

<a href="<API_ENDPOINT>?token=<token>&param1=something&param2=something">download</a>

Это может сработать, привязав параметры к URLстрока.Однако я бы не советовал использовать этот метод, если у вас нет способа создать SIGNED SINGLE USE GET AUTHENTICATION TOKENS , так как вы никогда не должны отправлять токены доступа в любое место для чтения.

Вариант 2 - создать универсальныйHTML-форма, где действие является конечной точкой API, где вы можете передать токен в данных поста.Если ваша конечная точка API просто возвращает правильный файл, то при отправке формы файл должен быть загружен, и вы сможете остаться на той же странице.

<form action="<API ENDPOINT>" method="post">
  <!-- Standard input types named appropriately
</form>

Это всего лишь пара решений.Мне лично нравится вариант 1, но только если вы можете обеспечить его безопасную работу.Исследуйте методы аутентификации HMAC, чтобы создать этот одноразовый токен, если вы можете хранить и управлять одноразовыми номерами на серверной части.Хорошо работает с JWT.

0 голосов
/ 20 февраля 2019

Ответ был просто добавить dataType: 'arraybuffer':

...
jquery.ajax({
    url: 'myUrl',
    data: formData,
    processData: false,
    contentType: false,
    dataType: 'arraybuffer',
    beforeSend: function(xhr) {
...
...