Загрузите возвращенный PDF-файл из Ajax

У меня есть следующее действие, которое возвращает PDF:

[HttpPost]
    public string GetPDF(string data, float scaleFactor)
    {
        var result = JArray.Parse(data);
        using (var fs = new FileStream(@"c:\pdf\pdftest.pdf", FileMode.Create))
        {
            MemoryStream ms = (MemoryStream)PdfMaker.CreatePDF(scaleFactor, result, dt);
            ms.WriteTo(fs);
            return Convert.ToBase64String(ms.ToArray());
        }
    }

(Игнорируйте FileStream, это только для тестирования)
Результатом является в основном сам PDF-файл, но он не загружается. Как мне загрузить выходной PDF-файл? Должен ли я вернуть что-нибудь еще? Я пробовал использовать FileResult, но в основном тот же сценарий.

Вот как я сейчас "читаю" файл через Ajax:

$.ajax({
    type: "POST",
    url: "home/GetPDF",
    data: { data: JSON.stringify(data), scaleFactor: $("#sf").val() },   
    success: function (data) {      

        window.location = "data:application/pdf;base64, " + data;
    }
});

Спасибо.

Редактировать:

Использовал решение в сообщении это, предоставленное Стивеном Мьюке.

Какой аякс? Покажи свой код.

user3559349 07.06.2018 11:02

почему бы просто не сделать window.location непосредственно для действия GetPDF и не вернуть FileResult с обычным файлом в нем? Загрузка файлов через ajax не работает, потому что данные попадают в память в объекте JS, а не на устройстве пользователя. Просто используйте обычный HTTP-запрос.

ADyson 07.06.2018 11:10

Файл создается на основе пользовательского ввода на странице, как я могу напрямую указать window.location для него, поскольку он имеет динамические параметры?

master2080 07.06.2018 11:11

в этом случае используйте обратную передачу формы, чтобы вы могли легко отправить данные

ADyson 07.06.2018 11:13

Обратитесь к этот ответ для примера

user3559349 07.06.2018 11:13

@ADyson Мне нужно оставаться на странице.

master2080 07.06.2018 11:14

Есть также способы создания PDF-файлов с использованием JavaScript без необходимости отправлять что-либо на сервер, если вы выполняете поиск в Интернете.

ADyson 07.06.2018 11:15

@ADyson Я должен генерировать PDF-файлы таким образом, он должен поступать с сервера.

master2080 07.06.2018 11:16

Или другой вариант - отправить данные на сервер с помощью AJAX, сохранить файл во временной папке, вернуть идентификатор файла, затем выполнить window.open для второго действия с помощью GET и передать идентификатор файла, который будет выполнять скачать

ADyson 07.06.2018 11:16

"он должен поступать с сервера" ... вы только что сказали, что данные поступают от клиента. так кого волнует, генерирует ли его сервер или браузер? Результат тот же.

ADyson 07.06.2018 11:17

@ADyson PDF-файл должен быть создан на сервере, а не в данных от клиента. Нет возможности создавать PDF-файлы с использованием javascript с моими требованиями.

master2080 07.06.2018 11:17

Вы совершенно четко сказали: «Файл создается на основе ввода данных пользователем на странице». Итак, данные есть на странице в браузере. Он уже находится на машине клиента. Итак, почему в этом сценарии PDF-файл должен создаваться сервером? Добавляет ли сервер дополнительные данные? Должна ли копия файла храниться на сервере? Вы не упомянули ни то, ни другое как требования. Если это не требования, то, если вы не можете указать другую причину, кроме тавтологического «он должен», то, насколько я могу судить, сервер не добавляет никакой ценности процессу.

ADyson 07.06.2018 11:20

Потому что это не имело отношения к проблеме. Я не создаю новый PDF напрямую, а редактирую существующий на сервере с вводом пользователя. Javascript не имеет доступа к подобным материалам.

master2080 07.06.2018 11:21

ну что ж, вы не изложили ситуацию полностью, отсюда и мое недоразумение. Также ваш пример кода вызывает CreatePDF, так что простите меня за то, что я подумал, что вы создавали новый.

ADyson 07.06.2018 11:21

Потому что это не имеет отношения к моему вопросу. Мой вопрос в том, как скачать PDF-файл, а не сделать его.

master2080 07.06.2018 11:21

@ADyson Не могли бы вы превратить часть временной папки в ответ? Это кажется возможным решением.

master2080 07.06.2018 11:22

Да, но если загрузка неудобна, как в данном случае, то можно предложить альтернативный подход, основанный на доступной информации. В любом случае, попробуйте ссылку, опубликованную Стивеном, или мое предыдущее предложение отправить данные на сервер с помощью AJAX, сохранить файл во временной папке, вернуть идентификатор файла, затем выполнить window.open для второго действия с помощью GET и передача идентификатора файла, который будет выполнять загрузку. Я постараюсь изложить это как правдоподобный ответ.

ADyson 07.06.2018 11:22
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
17
120
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Загрузка файлов через ajax не работает, потому что данные попадают в память в объекте JS, а не на устройстве пользователя. В конечном итоге вам нужно использовать обычный HTTP-запрос и вернуть FileResult.

Однако в вашем случае вам также необходимо сначала загрузить некоторые данные, которые необходимо добавить в PDF-файл перед его загрузкой. Это неудобно, потому что загрузка должна быть запросом GET, запускаемым в отдельном окне (потому что вам нужно, чтобы приложение оставалось на той же странице после этого), и предоставление этих данных в строке запроса вряд ли будет практичным.

Решение обойти это состоит в том, чтобы иметь двухэтапный процесс:

1) Из браузера загрузите свои данные через AJAX в метод действия «EditPDF». В методе действия отредактируйте PDF-файл, используя новые данные, и сохраните его. Затем верните клиенту какой-то уникальный идентификатор, который определяет правильный PDF-файл.

2) Когда браузер получает ответ от метода EditPDF, он захватывает возвращенный идентификатор и делает новый вызов window.open для URL-адреса действия «GetPDF». Это действие принимает идентификатор PDF в качестве параметра строки запроса, поэтому его легко включить в URL-адрес при выполнении запроса. Это действие находит правильный документ на сервере и возвращает его в FileResult. Браузер загрузит документ, не влияя на просматриваемую HTML-страницу.

Хорошее резюме ответа, связанного Стивеном. Спасибо.

master2080 07.06.2018 11:44

Другие вопросы по теме