2016-08-22 3 views
4

Я пытаюсь реализовать эти, казалось бы, простые требования, но не могу найти путь:Как открыть файл CSV, порожденную POST

  • одностраничного App с помощью Угловой JS
  • REST (МОГ) задний конец
  • Назад конец ресурс подвергается через запрос POST
  • параметры ресурсов передаются как JSON в теле запроса
  • ресурс производит CSV файл
  • Когда пользователь нажимает кнопку, генерирует запрос с правильными параметрами JSON в теле, отправляет его и разрешает пользователю загружать ответ в виде файла (запрашивает диалоговое окно «открыть/сохранить как браузер»)

Проблема в основном, как передать JSON в качестве тела запроса? Наиболее распространенным методом является скрытая форма HTML для запуска загрузки, но форма HTML не может отправлять данные JSON в тело. И я не могу найти способ запуска диалогового окна загрузки с помощью XMLHttpRequest ...

Любые идеи?

Я определил Угловое, но любое общее решение JS тоже очень приветствуется!

+0

Помогает ли это: http://stackoverflow.com/questions/14551194/how-are-parameters-sent-in-an-http-post-request И можете ли вы опубликовать фрагмент, как сделать JS HTTP-вызов? Если речь идет о диалоговом окне загрузки, вам нужно указать дополнительный заголовок. – Markus

+3

Ответ должен содержать «Контент-раскладка: вложение», установленный в заголовках, чтобы браузер отображал диалог «открыть/сохранить как». JSON этого не сделает, если вы не выполните пост JSON и не перенаправите URL-адрес – Dimitri

+0

@ Dimitri: да, это уже так.Запрос содержит JSON в теле, ответ содержит CSV с правильными заголовками, включая «Content-Disposition» –

ответ

0

Наконец-то я нашел решение, которое удовлетворяет всем моим требованиям и работает в IE11, FF и Chrome (и ухудшает вид OK в Safari ...).

Идея состоит в том, чтобы создать объект Blob, содержащий данные из ответа, а затем заставить браузер открыть его в виде файла. Он немного отличается для IE (фирменный API) и Chrome/FF (с использованием элемента ссылки).

Вот реализация, как небольшие угловые службы:

myApp.factory('Download', [function() { 
    return { 
     openAsFile : function(response){ 

      // parse content type header 
      var contentTypeStr = response.headers('Content-Type'); 
      var tokens = contentTypeStr.split('/'); 
      var subtype = tokens[1].split(';')[0]; 
      var contentType = { 
       type : tokens[0], 
       subtype : subtype 
      }; 

      // parse content disposition header, attempt to get file name 
      var contentDispStr = response.headers('Content-Disposition'); 
      var proposedFileName = contentDispStr ? contentDispStr.split('"')[1] : 'data.'+contentType.subtype; 

      // build blob containing response data 
      var blob = new Blob([response.data], {type : contentTypeStr}); 

      if (typeof window.navigator.msSaveBlob !== 'undefined'){ 
       // IE : use proprietary API 
       window.navigator.msSaveBlob(blob, proposedFileName); 
      }else{ 
       var downloadUrl = URL.createObjectURL(blob); 

       // build and open link - use HTML5 a[download] attribute to specify filename 
       var a = document.createElement("a"); 

       // safari doesn't support this yet 
       if (typeof a.download === 'undefined') { 
        window.open(downloadUrl); 
       } 

       var link = document.createElement('a'); 
       link.href = downloadUrl; 
       link.download = proposedFileName; 
       document.body.appendChild(link); 
       link.click(); 
       document.body.removeChild(link); 
      } 
     } 
    } 
}]); 

Аргумент ответа ожидает объект $http ответа. Ниже приведен пример использования с запросом POST:

$http.post(url, {property : 'value'}, {responseType: 'blob'}).then(function(response){ 
    Download.openAsFile(response); 
}); 

Примечание параметр responseType. Без этого мои CSV-данные считывались как текст и сохранялись в памяти как UTF-8 (или 16), а затем файл сохранялся в той же кодировке, в результате чего Excel не распознавал специальные символы, такие как éè и т. Д. Так как мои CSV предназначены для открытия Excel, сервер кодирует их Windows 1252, я хотел сохранить их таким образом. Установка этого параметра responseType на blob достигает этого.

Отказ от ответственности: Он должен работать с любым типом файла. Но я тестировал его только с файлами CSV! Двоичные файлы могут вести себя как-то иначе!

Смежные вопросы