загрузка исходного файла с помощью JavaScript
Допустим, у меня есть ссылки для загрузки файлов на моем сайте.
при нажатии на эти ссылки отправить AJAX-запрос на сервер, который возвращает URL-адрес с расположением файла.
Что я хочу сделать, это направить браузер, чтобы загрузить файл, когда ответ вернется. Есть ли портативный способ сделать это?
12 ответов:
попробуйте эту lib https://github.com/PixelsCommander/Download-File-JS это более современный, чем все решения, описанные ранее, потому что использует атрибут "скачать" и комбинацию методов, чтобы принести наилучший возможный опыт.
объяснил здесь - http://pixelscommander.com/en/javascript/javascript-file-downliading-ignore-content-type/
кажется, это идеальный кусок кода для начала загрузки в JavaScript.
мы делаем это таким образом: Сначала добавьте этот скрипт.
<script type="text/javascript"> function populateIframe(id,path) { var ifrm = document.getElementById(id); ifrm.src = "download.php?path="+path; } </script>поместите это туда, где вы хотите кнопку загрузки(здесь мы используем только ссылку):
<iframe id="frame1" style="display:none"></iframe> <a href="javascript:populateIframe('frame1','<?php echo $path; ?>')">download</a>скачать файл'.php' (должен быть помещен на ваш сервер) просто содержит:
<?php header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=".$_GET['path']); readfile($_GET['path']); ?>поэтому, когда вы нажимаете ссылку, скрытый iframe затем получает / открывает загрузку исходного файла.php'. С помощью пути в качестве параметра get. Мы считаем, что это лучшее решение!
следует отметить, что PHP часть это решение является простой демонстрацией и потенциально очень, очень небезопасно. Это позволяет пользователю загружать любой файл, а не только заранее определенный набор. Это означает, что они могут загружать части исходного кода самого сайта, возможно, содержащие учетные данные API и т. д.
Я создал с открытым исходным кодом jQuery file Download plugin (демо с примерами) (GitHub), который также может помочь в вашей ситуации. Он работает довольно похоже с iframe, но имеет некоторые интересные функции, которые я нашел довольно удобно:
- пользователь никогда не покидает ту же страницу, с которой он начал загрузку файла. Эта функция становится важной для современных веб-приложений
- тестирование кросс-браузер поддержка (в том числе мобильный!)
- он поддерживает POST и GET запросы таким же образом, как jQuery AJAX API
- successCallback и failCallback функции позволяют вам быть явным о том, что пользователь видит в любой ситуации
- в сочетании с jQuery UI разработчик может легко показать модальное сообщение пользователю о том, что происходит загрузка файла, распустить модальное после начала загрузки или даже сообщить пользователю в дружественной форме, что произошла ошибка. См. демонстрацию для примера этого.
чтение ответов-включая принятый я хотел бы указать на последствия для безопасности прохождения пути непосредственно к readfile через GET.
Это может показаться очевидным для некоторых, но некоторые могут просто скопируйте/вставьте этот код:
<?php header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=".$_GET['path']); readfile($_GET['path']); ?>Так что произойдет, если я передам что-то вроде '/path/to/fileWithSecrets' в этот скрипт? Данный скрипт с радостью отправит любой файл, к которому имеет доступ веб-сервер-пользователь.
пожалуйста, обратитесь к этому обсуждению для получения информации как предотвратить это: как я могу убедиться, что путь к файлу находится в заданном подкаталоге?
Если это ваше собственное серверное приложение, то я предлагаю использовать следующий заголовок
Content-disposition: attachment; filename=fname.extэто заставит любой браузер загрузить файл и не отображать его в окне браузера.
просто позвони
window.location.href = new_urlиз вашего javascript, и он перенаправит браузер на этот URL, как это пользователь ввел это в адресную строку
a согласен с методами, упомянутыми maxnk, однако вы можете пересмотреть попытку автоматически заставить браузер загружать URL-адрес. Он может отлично работать для двоичных файлов, но для других типов файлов (текст, PDF, изображения, видео) браузер может захотеть отобразить его в окне (или IFRAME), а не сохранять на диск.
Если вам действительно нужно сделать вызов Ajax, чтобы получить окончательные ссылки для загрузки, как насчет использования DHTML для динамической записи ссылки для загрузки (от ответ ajax) на страницу? Таким образом, пользователь может либо нажать на него, чтобы загрузить (если двоичный) или просмотреть в своем браузере - или выбрать "Сохранить как" по ссылке, чтобы сохранить на диск. Это лишний клик, но пользователь имеет больше контроля.
чтобы обойти недостаток безопасности в верхнем голосовании, вы можете установить iframe src непосредственно в файл, который вы хотите (вместо промежуточного файла php), и установить информацию о заголовке в an .файл htaccess:
<Files *.apk> ForceType application/force-download Header set Content-Disposition attachment Header set Content-Type application/vnd.android.package-archive Header set Content-Transfer-Encoding binary </Files>
Я предлагаю сделать невидимый iframe на странице и установить его src на url, который вы получили с сервера - загрузка начнется без перезагрузки страницы.
или вы можете просто установить текущий документ.местоположение.href на полученный url-адрес. Но это может привести к тому, что пользователь увидит ошибку, если запрошенный документ на самом деле не существует.
в отношении верхнего ответа у меня есть возможное решение проблемы безопасности.
<?php if(isset($_GET['path'])){ if(in_array($_GET['path'], glob("*/*.*"))){ header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=".$_GET['path']); readfile($_GET['path']); } } ?>С помощью функции glob () (я протестировал файл загрузки в пути одной папки из файла, который будет загружен) я смог сделать быстрый массив файлов, которые "разрешены" для загрузки и проверил пройденный путь против него. Это не только гарантирует, что захваченный файл не является чем-то чувствительным, но и проверяет наличие файлов одновременно время.
~Примечание: Javascript / HTML~
HTML:
<iframe id="download" style="display:none"></iframe>и
<input type="submit" value="Download" onclick="ChangeSource('document_path');return false;">JavaScript:
<script type="text/javascript"> <!-- function ChangeSource(path){ document.getElementByID('download').src = 'path_to_php?path=' + document_path; } --> </script>
Я бы предложил
window.open()открыть всплывающее окно. Если это загрузка, не будет никакого окна, и вы получите свой файл. Если есть 404 или что-то еще, пользователь увидит его в новом окне (следовательно, их работа не будет беспокоить, но они все равно получат сообщение об ошибке).
почему вы делаете вещи на стороне сервера, когда все, что вам нужно, это перенаправить браузер в другое окно.местоположение.Солар?
вот код, который парсит ?file= QueryString ( взято из этого вопроса) и перенаправляет пользователя на этот адрес за 1 секунду (работает для меня даже в браузерах Android):
<script type="text/javascript"> var urlParams; (window.onpopstate = function () { var match, pl = /\+/g, // Regex for replacing addition symbol with a space search = /([^&=]+)=?([^&]*)/g, decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, query = window.location.search.substring(1); urlParams = {}; while (match = search.exec(query)) urlParams[decode(match[1])] = decode(match[2]); })(); (window.onload = function() { var path = urlParams["file"]; setTimeout(function() { document.location.href = path; }, 1000); }); </script>Если у вас есть jQuery в вашем проекте, определенно удалите это окно.onpopstate & window.onload обработчики и сделать все в $(документ).готов(функция () { } );
Comments