Возникла задача ― загрузить с сервера XLSX-файл. Запрос ― POST. Файл, понятное дело, бинарный. На проекте уже подключена jQuery, и, первым делом, я решил воспользоваться её стандартным $.ajax. Сколько не бился ― так и не удалось получить blob-результат от запроса. Использовать же решение через iframe-ы и form-ы тоже не хотелось. Во-первых уж больно костыльно (привет 90-ые). во-вторых нужно будет ещё чудить с передачей параметров POST-запроса (content-type: json). Гуглил-гуглил, но ни одного вменяемого решения (которое не стыдно было бы утащить в проект) я так и не нашёл. Но, т.к. интересует поддержка только последних версий современных браузеров, удалось найти и применить более изящное и функциональное решение. Итак…
- Забудем про
jQueryи воспользуемся нативнымXMLHttpRequest-ом - Указав ему
responseType = ‘blob’. - Получившийся результат (
blob) загоняем вURL.createObjectURL. - В результате получим псевдо-URL ссылку, начинающуюся с “
blob:”.
Ну а дальше уже по-желанию. Я генерирую новый <a/>-тег, задаю ему нужные аттрибуты download и href (та самая blob-ссылка), вызываю у ссылки .click(). Апосля ссылку удаляю. Проверял в Firefox-е и Chrome-е.
Небольшая заготовка:
function loadBlob(params, data) { return new Promise((resolve, reject) => { const xhr = _.assign(new XMLHttpRequest(), { onload(){ resolve(xhr.response); }, onerror(e){ reject(e.target.status); } }); xhr.open(params.method || 'POST', params.url); xhr.responseType = 'blob'; const contentType = params.contentType || 'application/json'; xhr.setRequestHeader('content-type', contentType); if(contentType === 'application/json') data = JSON.stringify(data); xhr.send(data); }); }
