Всем привет. Столкнулся с проблемой передача pdf файла с сервера на скачивание клиенту. Код (Javascript): //Нажатие на кнопку Сохранить function btn_for_pdf_download_polzovatel_card_click_function() { $.ajax({ type: 'POST', url: "../../../ajax/fpdf_function.php", xhrFields: { responseType: 'blob' }, success: function (data) { var a = document.createElement('a'); var url = window.URL.createObjectURL(data); a.href = url; a.download = 'report.pdf'; document.body.append(a); a.click(); } }); } //Конец Нажатие на кнопку Сохранить PHP: //....формирование report.pdf //..................................... header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="report.pdf"'); readfile('report.pdf'); Здесь при нажатии на кнопку, должно предлагаться сохранить файл. Но, почему то не работает.
Вот что выдает мне отладчик браузера Код (Text): InvalidStateError: responseText is only available if responseType is '' or 'text'
ну это да, у тебя же 'blob' **** и да, это у тебя из Node.js что ли функция вызывается, на сервере? или откуда? //это НЕ риторический вопрос)) просто вот относительный путь: Код (Text): url: "../../../ajax/fpdf_function.php", не совсем понятно относительно чего именно --- Добавлено --- кароч, подозреваю что ты с путями что-то намудрил)) но отладку стоит начать вот с чего: - передай ему вместо pdf - обычный текст с сервера - и соответственно responseType:'blob' измени на 'text' как он хочет - посмотрим что оно скажет)))
Сервер вернул кракозябры Код (Text): %PDF-1.3 3 0 obj <</Type /Page /Parent 1 0 R /Resources 2 0 R /Contents 4 0 R>> endobj 4 0 obj <</Filter /FlateDecode /Length 325>> stream x�}�MK�0������ 1M�o~!��c3m�ݤ������f<Ho a�yg��b�����p�\@-���<U�#$_$Z�cY�b�r�j�����`!u���[��ɥ1��[�Rz�ר>��_Nm��f��1�Z�H�7�S�or���@�ºy����C�������>T'��wQ�b��cHݬ�v�P�lGF)`�-9 ��O9�����p����7k��YL���;xz�E��w���x�:���]�ys�j��8�3\�})�k�J�e�Q���(� q;�����/���V�2sm�S��sMt6ut���P�ѥ`)����ʻd endstream --- Добавлено --- Может что то с заголовками не то?
Да не, это же он pdf и вернул небось)) Ладно, не суть, скажи, а ты этот относительный путь относительно чего прописал-то? Каков контекст исполнения этой функции? Это что - обычный джаваскрипт исполняемый в браузере? А каков урл файла в адресной строке браузера?
Относительно файла, в котором JS код. Но даже, если url="fpdf_function.php", т.е. серверный php-скрипт в корне сайта, ситуация не меняется. Если бы дело было в путях, то ajax-метод вообще не работал бы никак. А так мы видим, что что-то возвращается. fpdf_function.php- это скрипт, который внутри генерит файл pdf (при помощи класса FPDF), ложит его в папку и отдает клиенту на скачивание. php- это серверный скрипт, исполняемый на сервере localhost:8080/admin/html_view/html/polzovatel_card.html
Максимально упростил задачу. Создал новый простой проект. Все файлы в корне. HTML: <!DOCTYPE html> <html> <head> <title>Тестовый проект</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="jquery-ui-1.12.1.custom/jquery-ui.structure.min.css" rel="stylesheet" type="text/css"/> <link href="jquery-ui-1.12.1.custom/jquery-ui.min.css" rel="stylesheet" type="text/css"/> <link href="jquery-ui-1.12.1.custom/jquery-ui.theme.min.css" rel="stylesheet" type="text/css"/> <script src="jquery-ui-1.12.1.custom/external/jquery/jquery.js" type="text/javascript"></script> <script src="jquery-ui-1.12.1.custom/jquery-ui.min.js" type="text/javascript"></script> <script src="jquery-ui-1.12.1.custom/jquery-ui.js" type="text/javascript"></script> <script src="test.js" type="text/javascript"></script> </head> <body> <input type="button" value="Скачать" id="btn_test" /> </body> </html> Код (Javascript): $(document).ready(function () { $('#btn_test').button(); $('#btn_test').click(function () { $.ajax({ url: "test_php.php", xhrFields: { responseType: "blob" }, success: function (data, status, xhr) { //alert(data); var blob = new Blob([data], {type: 'image/jpg'}); var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = 'test_image.jpg'; link.click(); } }); }); }); PHP: <?php $file_name = 'test_image.jpg'; Header("HTTP/1.1 200 OK"); Header("Connection: close"); Header("Content-Type: application/octet-stream"); Header("Accept-Ranges: bytes"); Header("Content-Disposition: Attachment; filename=".$file_name); Header("Content-Length: 50000"); readfile($file_name); И все равно ничего. Файл не отдается. Что за ...?
Так а если ты напрямую вызываешь test_php.php из браузера - он тебе отдает этот файл? Вот так: localhost:8080/path-to-file/test_php.php
Как-то много «лишних», причем в большинстве не самых простых заголовков. PHP: header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.$page['id'].'"'); header('Content-Length: '.strlen($page['content'])); echo $page['content']; Результат: http://g09.ru/file.txt
Да, напрямую пошло! --- Добавлено --- Оставил так: PHP: $file_name = 'test_image.jpg'; Header("Content-Type: application/octet-stream"); Header("Content-Disposition: Attachment; filename=".$file_name); readfile($file_name); Напрямую отдает, через AJAX не хочет.
А что AJAX? Тут специальные техники используются вплоть до скрытого фрэйма. Когда-то оставлял на форуме пост на эту тему, но не смог его найти. Посмотри либы вроде filesaver.js и т.п.
Ну, думаю, для начала имеет таки смысл прописать вместо Код (Text): url: "test_php.php", полный урл, по которому он тебе отдает этот файл, а дальше уже смотреть по ситуации
С учетом всех замечаний: Код (Javascript): $(document).ready(function () { $('#btn_test').button(); $('#btn_test').click(function () { $.ajax({ type: 'POST', url: "http://test:8080/test_php.php", xhrFields: { responseType: "blob" }, success: function (data, status, xhr) { var blob = new Blob([data], {type: xhr.getResponseHeader('Content-Type')}); var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = 'test_image.jpg'; link.click(); } }); }); }); PHP: <?php $file_name = 'test_image.jpg'; Header("Content-Type: application/octet-stream"); Header("Content-Disposition: Attachment; filename=".$file_name); readfile($file_name); Все равно ошибка та же Код (Text): InvalidStateError: responseText is only available if responseType is '' or 'text'. Но уже в отладчике браузера размер переданных байт уже соответствует действительности. Сейчас 746Kb, раньше было где то 48б.
Ну в общем-то, так как хотел не получается. Может что то с версией jQuery? Решил обойти проблему, следующим образом. При загрузке страницы в php-скрипте формируется pdf-файл и через AJAX-метод отдается имя файла. После удачной обработки (success (name_file){...}) в ссылке формируется href="...".