Страницы

Поиск по вопросам

четверг, 23 января 2020 г.

c# jquery ajax сохранение pdf

#c_sharp #ajax #pdf


Имеется метод в контроллере, который возвращает FileContentResult:

return File(pdfBytes, "application/pdf", "DownloadName.pdf");


Проблема в том, как с помощью jquery ajax в клиентской части получить и сохранить
файл в формате pdf.
Как решить данную проблему?
    


Ответы

Ответ 1



Браузеры (и соответственно, jQuery) не умеют корректно сохранять файлы, приходящие в ответ на ajax-запрос. Если файл нужно отдавать в ответ на POST-запрос и нужно поддерживать старые браузеры, то единственный надежный вариант - делать обычный полноэкранный POST. Если файл нужно отдавать в ответ на GET-запрос, то достаточно просто заменить ajax вызов обычным GET-ом: window.location.href = <ссылка на файл>; Если в ответ на такое с сервера придет файл - он просто скачается, и пользователь останется на текущей странице. В более новых браузерах файл, пришедший в ответ на ajax, можно сохранить через FileAPI. На всякий случай проверьте таблицу поддержки FileAPI - вдруг вам нужно поддерживать какой-нибудь IE9. Решение через FileAPI (честно скопировано с enSO): var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.responseType = 'arraybuffer'; xhr.onload = function () { if (this.status === 200) { var filename = ""; var disposition = xhr.getResponseHeader('Content-Disposition'); if (disposition && disposition.indexOf('attachment') !== -1) { var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; var matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, ''); } var type = xhr.getResponseHeader('Content-Type'); var blob = new Blob([this.response], { type: type }); if (typeof window.navigator.msSaveBlob !== 'undefined') { // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed." window.navigator.msSaveBlob(blob, filename); } else { var URL = window.URL || window.webkitURL; var downloadUrl = URL.createObjectURL(blob); if (filename) { // 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.location = downloadUrl; } else { a.href = downloadUrl; a.download = filename; document.body.appendChild(a); a.click(); } } else { window.location = downloadUrl; } setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup } } }; xhr.send($.param(params));

Ответ 2



Схема с максимальной поддержкой браузеров Посылаешь запрос на сервер, в ответ скрипту приходит некий id и имя файла. Скрипт выполняет такое: window.location.href = 'http://some.site.ru/any/' + id + '/' + filename Сервер посылает файл, не забыв указать content-disposition: attachment Браузер скачивает файл, оставаясь на той же страницы. Почему имя файла url, а не в заголовке ответа? Потому что filename* понимают не все, энкодинг понимают не все, можно указать только одно из filename и filename*, иначе будет запрос пользователю про множественные файлы. В общем, проще упихать имя в url, чем разгребать, что за браузер послал запрос и каким заголовком на него ответить. На что ещё обратить внимание? У тебя pdf-файл. Это может оказаться существенным для хрома. Он считает себя особенным и пытается открывать pdf сам, даже если делается попытка открыть уже скачанный файл. Обязательно проверить, как современные хромы реагируют на вышеописанный способ.

Комментариев нет:

Отправить комментарий