Загрузка файла с помощью 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")
С открытым окном откройте страницу загрузки, которая автоматически закрывается.