Подтвердить что ты не робот

Загрузка исходного файла с помощью JavaScript

Скажем, у меня есть ссылки для скачивания файлов на моем сайте.

При нажатии этих ссылок отправьте запрос AJAX на сервер, который возвращает URL-адрес с расположением файла.

То, что я хочу сделать, - это прямой браузер для загрузки файла, когда ответ вернется. Есть ли способ передвижения?

4b9b3361

Ответ 1

Попробуйте этот lib https://github.com/PixelsCommander/Download-File-JS, это более современно, чем все описанные ранее решения, поскольку использует атрибут "загрузить" и комбинацию методов для приведения наилучший опыт.

Разъяснение здесь - http://pixelscommander.com/en/javascript/javascript-file-downliading-ignore-content-type/

Кажется, это идеальный фрагмент кода для начала загрузки в JavaScript.

Ответ 2

Мы делаем это так: Сначала добавьте этот script.

<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>

Файл 'download.php' (должен быть помещен на ваш сервер) просто содержит:

<?php 
   header("Content-Type: application/octet-stream");
   header("Content-Disposition: attachment; filename=".$_GET['path']);
   readfile($_GET['path']);
?>

Итак, когда вы нажимаете ссылку, скрытый iframe затем получает/открывает исходный файл "download.php". С параметром get как get. Мы считаем, что это лучшее решение!

Следует отметить, что часть PHP этого решения является простой демонстрацией и потенциально очень, очень небезопасной. Он позволяет пользователю загружать любой файл, а не только определенный набор. Это означает, что они могут загружать части исходного кода самого сайта, возможно, содержащие учетные данные API и т.д.

Ответ 3

Я создал открытый источник плагин загрузки файла jQuery (Демо с примеры) (GitHub), которые также могут помочь в вашей ситуации. Он работает аналогично с iframe, но имеет некоторые интересные функции, которые я нашел весьма удобными:

  • Пользователь никогда не покидает ту же страницу, с которой они инициировали загрузку файла. Эта функция приобретает решающее значение для современных веб-приложений.
  • Проверенная поддержка кросс-браузера (включая мобильный!)
  • Он поддерживает запросы POST и GET способом, подобным API jQuery AJAX
  • successCallback и функции failCallback позволяют вам четко указывать, что пользователь видит в любой ситуации.
  • В сочетании с jQuery UI разработчик может легко показать модальное сообщение пользователю о том, что загрузка файла происходит, распустить модальный после начала загрузки или даже сообщить пользователю дружеским образом, что произошла ошибка. См. Демонстрацию на примере этого.

Ответ 4

Чтение ответов - включая принятое, я хотел бы указать на последствия безопасности для передачи пути непосредственно в readfile через GET.

Это может показаться очевидным для некоторых, но некоторые могут просто скопировать/вставить этот код:

<?php 
   header("Content-Type: application/octet-stream");
   header("Content-Disposition: attachment; filename=".$_GET['path']);
   readfile($_GET['path']);
?>

Итак, что произойдет, если передать этот script что-то вроде '/path/to/fileWithSecrets'? Данный script с радостью отправит любой файл, к которому имеет доступ пользователь веб-сервера.

Пожалуйста, ознакомьтесь с этим обсуждением, как предотвратить это: Как убедиться, что путь к файлу находится в заданном подкаталоге?

Ответ 5

Если это ваше собственное серверное приложение, я предлагаю использовать следующий заголовок

Content-disposition: attachment; filename=fname.ext

Это заставит любой браузер загружать файл и не отображать его в окне браузера.

Ответ 6

Просто позвоните window.location.href = new_url из своего javascript и перенаправит браузер на этот URL, как он набрал его в адресной строке

Ответ 7

Согласитесь с методами, упомянутыми maxnk, однако вы можете пересмотреть попытку автоматически заставить браузер загружать URL-адрес. Он может отлично работать для двоичных файлов, но для других типов файлов (текст, PDF, изображения, видео) браузер может захотеть отобразить его в окне (или IFRAME), а не сохранять на диск.

Если вам действительно нужно сделать вызов Ajax, чтобы получить окончательные ссылки для скачивания, как насчет использования DHTML для динамической записи ссылки загрузки (от ответа ajax) на страницу? Таким образом, пользователь может щелкнуть по нему, чтобы загрузить (в бинарном виде) или просмотреть в своем браузере, или выбрать "Сохранить как" в ссылке для сохранения на диск. Это дополнительный клик, но у пользователя больше контроля.

Ответ 8

Чтобы обойти уязвимость безопасности в ответе на верхний голос, вы можете установить iframe src непосредственно в нужный файл (вместо промежуточного файла php) и задать информацию заголовка в файле .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>

Ответ 9

Я предлагаю сделать невидимый iframe на странице и установить его src для URL-адреса, который вы получили с сервера - загрузка начнется без перезагрузки страницы.

Или вы можете просто установить текущий документ .location.href на полученный адрес URL. Но это может привести к тому, что пользователь увидит ошибку, если запрошенный документ фактически не существует.

Ответ 10

В отношении верхнего ответа у меня есть возможное решение для риска безопасности.

<?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>

Ответ 11

Я предлагаю window.open() открыть всплывающее окно. Если это загрузка, окна не будет, и вы получите свой файл. Если есть 404 или что-то, пользователь увидит его в новом окне (следовательно, их работа не будет беспокоить, но они все равно получат сообщение об ошибке).

Ответ 12

Почему вы делаете серверные вещи, когда все, что вам нужно, это перенаправление браузера на разные window.location.href?

Вот код, который анализирует? 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 в вашем проекте, определенно удалите эти обработчики window.onpopstate и window.onload и сделайте все в $(document).ready(function() {});