Загрузка файла с помощью Javascript/jQuery

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

мне нужно, чтобы браузер пользователя начать загрузку вручную, когда $('a#someID').click();

но я не могу использовать window.href метод, поскольку он заменяет текущее содержимое страницы файлом, который вы пытаетесь загрузить.

Я хочу открыть загрузку в новом окне/вкладке. Как это возможно?

23 ответов


использовать невидимый <iframe>:

<iframe id="my_iframe" style="display:none;"></iframe>
<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

чтобы заставить браузер загрузить файл, который в противном случае был бы способен к рендерингу (например, HTML или текстовые файлы), вам нужен сервер для установки файла тип MIME до бессмысленного значения, такого как application/x-please-download-me или application/octet-stream, который используется для произвольных двоичных данных.

если вы только хотите открыть его в новой вкладке, единственный способ сделать это для пользователя, чтобы нажать на ссылку с его target атрибутом _blank.

в jQuery:

$('a#someID').attr({target: '_blank', 
                    href  : 'http://localhost/directory/file.pdf'});

при нажатии на ссылку, он загружает файл в новой вкладке/окне.


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

  • очень легко настроить с хорошими визуальными эффектами (jQuery UI Dialog, но не требуется), все тестируется слишком

  • пользователь никогда не оставляет ту же страницу, которую они инициировали загрузку файла от. Эта функция становится важной для современных веб-приложений

  • функции successCallback и failCallback позволяют вам быть явными о том, что пользователь видит в любой ситуации

  • в сочетании с jQuery UI разработчик может легко показать модальное сообщение пользователю о том, что происходит загрузка файла, распустить модальное после запуска загрузки или даже сообщить пользователю в дружественной манере, что произошла ошибка. Увидеть демо пример этого. Надеюсь, это кому-то поможет!

вот простой пример использования демо с помощью плагина источник с обещаниями. The демо-страницы включает в себя много других, "лучше UX" примеры, а также.

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}

проверьте, будет ли ваш целевой браузер(ы) запускать вышеуказанный фрагмент плавно:
http://caniuse.com/#feat=download


Я удивлен, что не много людей знают об атрибуте загрузки для элементов. Пожалуйста, помогите распространить слово об этом! У вас может быть скрытая html-ссылка и поддельный клик по ней. Если html-ссылка имеет атрибут загрузки, она загружает файл, а не просматривает его, несмотря ни на что. Вот код. Он загрузит изображение кошки, если сможет его найти.

document.getElementById('download').click();
<a href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download id="download" hidden></a>

Примечание.: Это не поддерживается во всех браузерах: http://www.w3schools.com/tags/att_a_download.asp


Я рекомендую использовать html5 для загрузки вместо jQuery:

<a href="your_link" download> file_name </a>

это загрузит ваш файл, не открывая его.


Если вы уже используете jQuery, вы можете использовать adventage для создания меньшего фрагмента
JQuery-версия ответа Андрея:

var $idown;  // Keep it outside of the function, so it's initialized once.
downloadURL : function(url) {
  if ($idown) {
    $idown.attr('src',url);
  } else {
    $idown = $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
  }
},
//... How to use it:
downloadURL('http://whatever.com/file.pdf');

только семь лет спустя появляется решение jQuery с одной строкой, использующее форму вместо iframe или ссылки:

$('<form></form>')
     .attr('action', filePath)
     .appendTo('body').submit().remove();

я протестировал это в

  • Chrome 55
  • Firefox 50
  • Edge IE8-10
  • iOS 10 (Safari/Chrome)
  • Android Chrome

Если кто знает какие минусы при таком решении я был бы очень рад услышать о них.


полный demo:

<html>
<head><script src="https://code.jquery.com/jquery-1.11.3.js"></script></head>
<body>
<script>
    var filePath = window.prompt("Enter a file URL","http://jqueryui.com/resources/download/jquery-ui-1.12.1.zip");
    $('<form></form>').attr('action', filePath).appendTo('body').submit().remove();
</script>
</body>
</html>

работает на Chrome, Firefox и IE8 и выше.

var link=document.createElement('a');
document.body.appendChild(link);
link.href=url ;
link.click();

простой пример использования iframe

function downloadURL(url) {
    var hiddenIFrameID = 'hiddenDownloader',
        iframe = document.getElementById(hiddenIFrameID);
    if (iframe === null) {
        iframe = document.createElement('iframe');
        iframe.id = hiddenIFrameID;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);
    }
    iframe.src = url;
};

тогда просто вызовите функцию, где вы хотите:

downloadURL('path/to/my/file');


наиболее полный и рабочий (протестированный) код для загрузки данных для FireFox, Chrome и IE код следующий. Предположим, что данные находятся в texarea


Я не знаю, слишком ли старый вопрос, но окно настройки.расположение url-адреса загрузки будет работать, если тип MIME загрузки правильный (например, zip-архив).

var download = function(downloadURL) {

   location = downloadURL;

});

download('http://example.com/archive.zip'); //correct usage
download('http://example.com/page.html'); //DON'T

чтобы улучшить ответ Imagine Breaker, это поддерживается в FF & IE:

var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

function downloadURI(uri, name) {
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.dispatchEvent(evt);
}

другими словами, просто используйте


ответ, представленный hitesh 30 декабря ' 13, действительно работает. Это просто требует небольшой настройки:

файл PHP может вызывать сам себя. Другими словами, просто создайте файл с именем "сохранить как".php, и поместите в него этот код...

        <a href="saveAs.php?file_source=YourDataFile.pdf">Download pdf here</a>

    <?php
        if (isset($_GET['file_source'])) {
            $fullPath = $_GET['file_source'];
            if($fullPath) {
                $fsize = filesize($fullPath);
                $path_parts = pathinfo($fullPath);
                $ext = strtolower($path_parts["extension"]);
                switch ($ext) {
                    case "pdf":
                    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
                    header("Content-type: application/pdf"); // add here more headers for diff. extensions
                    break;
                    default;
                    header("Content-type: application/octet-stream");
                    header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
                }
                if($fsize) {//checking if file size exist
                  header("Content-length: $fsize");
                }
                readfile($fullPath);
                exit;
            }
        }
    ?>

Я предлагаю вам использовать событие mousedown, которое вызывается перед событием click. Таким образом, браузер обрабатывает событие click естественным образом, что позволяет избежать любой странности кода:

(function ($) {


    // with this solution, the browser handles the download link naturally (tested in chrome and firefox)
    $(document).ready(function () {

        var url = '/private/downloads/myfile123.pdf';
        $("a#someID").on('mousedown', function () {
            $(this).attr("href", url);
        });

    });
})(jQuery);

отличное решение от Corbacho, я просто адаптировался, чтобы избавиться от var

function downloadURL(url) {
    if( $('#idown').length ){
        $('#idown').attr('src',url);
    }else{
        $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
    }
}

у меня были хорошие результаты с использованием тега формы, так как он работает везде, и вам не нужно создавать временные файлы на сервере. Метод работает следующим образом.

на стороне клиента (страница HTML) вы создаете невидимую форму, как это

<form method="POST" action="/download.php" target="_blank" id="downloadForm">
    <input type="hidden" name="data" id="csv">
</form>

затем вы добавляете этот код Javascript к своей кнопке:

$('#button').click(function() {
     $('#csv').val('---your data---');
     $('#downloadForm').submit();
}

на стороне сервера, у вас есть следующий PHP-код download.php:

<?php
header('Content-Type: text/csv');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=out.csv');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . strlen($data));

echo $_REQUEST['data'];
exit();

вы даже можете создавать zip-архивы данных вот так:

<?php

$file = tempnam("tmp", "zip");

$zip = new ZipArchive();
$zip->open($file, ZipArchive::OVERWRITE);
$zip->addFromString('test.csv', $_REQUEST['data']);
$zip->close();

header('Content-Type: application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="file.zip"');
readfile($file);
unlink($file); 

самое лучшее, что он не оставляет никаких остаточных файлов на вашем сервере, так как все создается и уничтожается на лету!


используя якорный тег и PHP, это можно сделать, проверьте этот ответ

jQuery Ajax вызов для загрузки PDF-файла

HTML
    <a href="www.example.com/download_file.php?file_source=example.pdf">Download pdf here</a>

PHP
<?php
$fullPath = $_GET['fileSource'];
if($fullPath) {
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "pdf":
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
        header("Content-type: application/pdf"); // add here more headers for diff. extensions
        break;
        default;
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    }
    if($fsize) {//checking if file size exist
      header("Content-length: $fsize");
    }
    readfile($fullPath);
    exit;
}
?>

Я проверяю размер файла, потому что если вы загружаете pdf из CDN cloudfront, вы не получите размер документа, который заставляет документ загружать в 0kb, чтобы избежать этого, я проверяю это условие

 if($fsize) {//checking if file size exist
      header("Content-length: $fsize");
    }

эти функции используются в stacktrace.js:

/**
 * Try XHR methods in order and store XHR factory.
 *
 * @return <Function> XHR function or equivalent
 */
var createXMLHTTPObject = function() {
    var xmlhttp, XMLHttpFactories = [
        function() {
            return new XMLHttpRequest();
        }, function() {
            return new ActiveXObject('Msxml2.XMLHTTP');
        }, function() {
            return new ActiveXObject('Msxml3.XMLHTTP');
        }, function() {
            return new ActiveXObject('Microsoft.XMLHTTP');
        }
    ];
    for (var i = 0; i < XMLHttpFactories.length; i++) {
        try {
            xmlhttp = XMLHttpFactories[i]();
            // Use memoization to cache the factory
            createXMLHTTPObject = XMLHttpFactories[i];
            return xmlhttp;
        } catch (e) {
        }
    }
}

/**
 * @return the text from a given URL
 */
function ajax(url) {
    var req = createXMLHTTPObject();
    if (req) {
        try {
            req.open('GET', url, false);
            req.send(null);
            return req.responseText;
        } catch (e) {
        }
    }
    return '';
}

Firefox и Chrome проверили:

var link = document.createElement('a');
link.download = 'fileName.ext'
link.href = 'http://down.serv/file.ext';

// Because firefox not executing the .click() well
// We need to create mouse event initialization.
var clickEvent = document.createEvent("MouseEvent");
clickEvent.initEvent("click", true, true);

link.dispatchEvent(clickEvent);

это на самом деле решение" chrome " для firefox (я не тестировал его в других браузерах, поэтому, пожалуйста, оставьте комментарии о компилируемости)


Я знаю, что опаздываю на вечеринку, но я хотел бы поделиться своим решением, которое является вариацией решения Imagine Breaker выше. Я попытался использовать его решение, потому что его решение кажется мне самым простым и легким. Но, как и другие, это не сработало для некоторых браузеров, поэтому я поставил некоторые варианты с помощью jquery.

надеюсь, что это может помочь кому-то там.

function download(url) {
  var link = document.createElement("a");
  $(link).click(function(e) {
    e.preventDefault();
    window.location.href = url;
  });
  $(link).click();
}

Примечание: не поддерживается во всех браузерах.

Я искал способ загрузить файл с помощью jquery без необходимости устанавливать url-адрес файла в атрибуте href с самого начала.

jQuery('<a/>', {
    id: 'downloadFile',
    href: 'http://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png',
    style: 'display:hidden;',
    download: ''
}).appendTo('body');

$("#downloadFile")[0].click();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Я использую решение@rakaloof без JQuery (потому что вам не нужно это здесь). Спасибо за идею! Вот решение на основе формы vanillaJS:

const uri = 'https://upload.wikimedia.org/wikipedia/commons/b/bb/Test_ogg_mp3_48kbps.wav';
let form = document.createElement("form");
form.setAttribute('action', uri);
document.body.appendChild(form);
form.submit();
document.body.removeChild(document.body.lastElementChild);

возможно, просто откройте страницу javascript, которая просто загружает файл, например, когда вы перетаскиваете ссылку для загрузки на новую вкладку:

Window.open("https://www.MyServer.
Org/downloads/ardiuno/WgiWho=?:8080")

С открытым окном откройте страницу загрузки, которая автоматически закрывается.