В последнее время я возился с WebGL и получил работу читателя Collada. Проблема в том, что она довольно медленная (Collada - очень подробный формат), поэтому я собираюсь начать конвертирование файлов в более простой в использовании формат (возможно, JSON). Дело в том, что у меня уже есть код для анализа файла в Javascript, поэтому я также могу использовать его в качестве моего экспортера! Проблема заключается в сохранении.
Теперь я знаю, что могу разобрать файл, отправить результат на сервер и попросить браузер запросить файл с сервера в качестве загрузки. Но на самом деле сервер не имеет никакого отношения к этому конкретному процессу, поэтому зачем его привлекать? У меня уже есть содержимое нужного файла в памяти. Есть ли способ, которым я мог бы представить пользователю загрузку с использованием чистого javascript? (Я сомневаюсь, но могу также спросить...)
И чтобы быть ясным: я не пытаюсь получить доступ к файловой системе без знаний пользователей! Пользователь предоставит файл (возможно, с помощью перетаскивания), script преобразует файл в память, и пользователю будет предложено загрузить результат. Все из которых должны быть "безопасными" действиями в отношении браузера.
[EDIT]: Я не упоминал об этом заранее, поэтому плакаты, которые ответили "Flash", достаточно действительны, но часть того, что я делаю, - это попытка подчеркнуть, что может быть сделано с чистым HTML5... так что Flash в моем случае. (Хотя это абсолютно правильный ответ для любого, кто делает "настоящее" веб-приложение.) В таком случае мне кажется, что мне не повезло, если я не хочу привлекать сервер. В любом случае, спасибо!
ОК, создавая данные: URI определенно делает трюк для меня, благодаря Мэтью и Деннкстеру, указывающим на этот вариант! Вот в основном, как я это делаю:
1) получить все содержимое в строку под названием "контент" (например, создав ее там изначально или путем чтения innerHTML тега уже построенной страницы).
2) Создайте URI данных:
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
Будут ограничения длины в зависимости от типа браузера и т.д., но, например, Firefox 3.6.12 работает до 256K. Кодирование в Base64 вместо использования encodeURIComponent может сделать вещи более эффективными, но для меня это нормально.
3) откройте новое окно и переадресовывайте его в этот URI, чтобы указать местоположение загрузки моей страницы, сгенерированной JavaScript:
newWindow = window.open(uriContent, 'neuesDokument');
Что это.
location.href
содержимое. location.href = uriContent
.
Простое решение для готовых браузеров HTML5...
function download(filename, text) {
var pom = document.createElement('a');
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
if (document.createEvent) {
var event = document.createEvent('MouseEvents');
event.initEvent('click', true, true);
pom.dispatchEvent(event);
}
else {
pom.click();
}
}
Использование
download('test.txt', 'Hello world!');
HTML5 определил метод window.saveAs(blob, filename)
. Он не поддерживается ни одним браузером прямо сейчас. Но есть библиотека совместимости, называемая FileSaver.js, которая добавляет эту функцию в большинство современных браузеров (включая Internet Explorer 10+). Internet Explorer 10 поддерживает метод navigator.msSaveBlob(blob, filename)
(MSDN), который используется в FileSaver.js для поддержки Internet Explorer.
Я написал сообщение с более подробной информацией об этой проблеме.
Длинные URI данных могут приводить к проблемам с производительностью в браузерах. Другой вариант сохранения созданных на стороне клиента файлов состоит в том, чтобы поместить их содержимое в объект Blob (или File) и создать ссылку для загрузки, используя URL.createObjectURL(blob)
. Это возвращает URL-адрес, который можно использовать для извлечения содержимого блоба. URL.revokeObjectURL()
хранится внутри браузера, пока не будет URL.revokeObjectURL()
в URL-адресе, или созданный документ закрыт. Большинство веб-браузеров поддерживают URL-адреса объектов, Opera Mini - единственная, которая их не поддерживает.
Если данные представляют собой текст или изображение, браузер может открыть файл, а не сохранять его на диск. Чтобы заставить файл загружаться при нажатии ссылки, вы можете использовать атрибут download
. Однако не все веб-браузеры поддерживают атрибут загрузки. Другой вариант - использовать application/octet-stream
в качестве файла mime-type, но это приводит к тому, что файл представляется как двоичный blob, который особенно непригоден для пользователя, если вы не укажете или не можете указать имя файла. См. Также " Сила, чтобы открыть" Сохранить как... "всплывающее окно в текстовой ссылке нажмите для pdf в HTML ".
Если blob создается с помощью конструктора файлов, вы также можете указать имя файла, но только для нескольких браузеров (включая Chrome и Firefox) есть поддержка конструктора файлов. Имя файла также может быть указано как аргумент атрибута download
, но это зависит от тонны соображений безопасности. Internet Explorer 10 и 11 предоставляет свой собственный метод msSaveBlob, чтобы указать имя файла.
var file;
var data = [];
data.push("This is a test\n");
data.push("Of creating a file\n");
data.push("In a browser\n");
var properties = {type: 'text/plain'}; // Specify the file mime-type.
try {
// Specify the filename using the File constructor, but ...
file = new File(data, "file.txt", properties);
} catch (e) {
// ... fall back to the Blob constructor if that isn't supported.
file = new Blob(data, properties);
}
var url = URL.createObjectURL(file);
document.getElementById('link').href = url;
<a id="link" target="_blank" download="file.txt">Download</a>
msSaveBlob
чтобы открыть диалоговое окно «Сохранить как». Для других браузеров единственный вариант - вручную выбрать «Сохранить как» в контекстном меню ссылки на скачивание.
function download(content, filename, contentType)
{
if(!contentType) contentType = 'application/octet-stream';
var a = document.createElement('a');
var blob = new Blob([content], {'type':contentType});
a.href = window.URL.createObjectURL(blob);
a.download = filename;
a.click();
}
Взгляните на Doug Neiner Downloadify, который является интерфейсом JavaScript на основе Flash для этого.
Downloadify - это небольшая библиотека JavaScript + Flash, которая позволяет генерировать и сохранять файлы "на лету" в браузере без взаимодействия с сервером.
HTML 5
и пометить соответственно? Это, вероятно, привлечет тех пользователей, которые знают об этой конкретной области (я полагаю, все еще сравнительно небольшая толпа сейчас). Я почти уверен, что это можно сделать в HTML 5, но я понятия не имею, как.
<a download="My-FileName.txt" href="data:application/octet-stream,HELLO-WORLDDDDDDDD">Click here</a>
Работает во всех современных браузерах (см. DEMO).
p.s. href
можно также установить с помощью Javascript: 'data:application/octet-stream,' + encodeURIComponent(content);
window.open()
нет атрибута загрузки (или какого-либо другого атрибута window.open()
. Это не имеет значения. Вы можете использовать этот метод и .click()
к нему .click()
, но посмотрите время, так как Firefox не понравится, если вы .click()
прежде чем позволить элементу присоединиться к телу.
Вы можете сгенерировать URI данных. Однако существуют ограничения, зависящие от браузера.
Я использовал FileSaver (https://github.com/eligrey/FileSaver.js), и он отлично работает.
Например, я сделал эту функцию для экспорта журналов, отображаемых на странице.
Вы должны передать массив для instanciation Blob, так что я просто, возможно, не написал это правильно, но он работает для меня.
На всякий случай, будьте осторожны с заменой: это синтаксис, чтобы сделать это глобальным, иначе он заменит только первый, который он встретит.
exportLogs : function(){
var array = new Array();
var str = $('#logs').html();
array[0] = str.replace(/<br>/g, '\n\t');
var blob = new Blob(array, {type: "text/plain;charset=utf-8"});
saveAs(blob, "example.log");
}
Я нашел два простых подхода, которые работают для меня. Сначала, используя уже нажатый элемент a
и вводя данные загрузки. А во-вторых, генерируем элемент a
с данными загрузки, выполняя a.click()
и удаляя его снова. Но второй подход работает только при вызове действия щелчка пользователя. (Некоторые) Браузерный блок click()
из других контекстов, например, при загрузке или срабатывании после таймаута (setTimeout).
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
function linkDownload(a, filename, content) {
contentType = 'data:application/octet-stream,';
uriContent = contentType + encodeURIComponent(content);
a.setAttribute('href', uriContent);
a.setAttribute('download', filename);
}
function download(filename, content) {
var a = document.createElement('a');
linkDownload(a, filename, content);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
</script>
</head>
<body>
<a href="#" onclick="linkDownload(this, 'test.txt', 'Hello World!');">download</a>
<button onclick="download('test.txt', 'Hello World!');">download</button>
</body>
</html>
a
в документ (возможно, с помощью "display:none"
), щелкнуть по нему, а затем удалить его.
Вот ссылка на метод URI данных, предложенный Мэтью, он работал на сафари, но не очень хорошо, потому что я не мог установить тип файла, он становится сохраненным как "неизвестный", а затем мне нужно вернуться туда позже и изменить это для просмотра файла...
Вы можете использовать localStorage. Это эквивалент файлов cookie Html5. Кажется, он работает на Chrome и Firefox, но на Firefox, мне нужно было загрузить его на сервер. То есть, тестирование непосредственно на моем домашнем компьютере не сработало.
Я работаю над примерами HTML5. Перейдите к http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html и прокрутите до лабиринта. Информация для восстановления лабиринта хранится с использованием localStorage.
Я пришел в эту статью, ища HTML5 JavaScript для загрузки и работы с XML файлами. Это то же самое, что и старый html и JavaScript????
Как уже упоминалось, File API, а также FileWriter и FileSystem API-интерфейсы могут использоваться для хранения файлов на клиентской машине из контекста вкладки/окна браузера.
Однако есть несколько вещей, относящихся к последним двум API, о которых вы должны знать:
Вот простые примеры того, как API используются, прямо или косвенно, в тандеме, чтобы сделать это:
bakedGoods.get({
data: ["testFile"],
storageTypes: ["fileSystem"],
options: {fileSystem:{storageType: Window.PERSISTENT}},
complete: function(resultDataObj, byStorageTypeErrorObj){}
});
Использование необработанных файлов, API FileWriter и FileSystem
function onQuotaRequestSuccess(grantedQuota)
{
function saveFile(directoryEntry)
{
function createFileWriter(fileEntry)
{
function write(fileWriter)
{
var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
fileWriter.write(dataBlob);
}
fileEntry.createWriter(write);
}
directoryEntry.getFile(
"testFile",
{create: true, exclusive: true},
createFileWriter
);
}
requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}
var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);
Хотя API-интерфейсы FileSystem и FileWriter больше не соответствуют стандартным трекам, их использование может быть оправдано в некоторых случаях, на мой взгляд, потому что:
Однако, если "некоторые случаи" охватывают ваши собственные, вы должны решить.
* BakedGoods поддерживается не кем иным, как этим парнем прямо здесь:)
Вот учебник по экспорту файлов в формате ZIP:
Перед тем, как начать работу, есть библиотека для сохранения файлов, имя библиотеки - fileSaver.js. Здесь вы можете найти эту библиотеку. Давайте начнем. Теперь включите необходимые библиотеки:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.4/jszip.min.js" type="text/javascript"></script>
<script type="text/javascript" src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.js" ></script>
Скопируйте этот код, и этот код загрузит zip файл с файлом hello.txt, имеющим контент Hello World. Если все работает нормально, это загрузит файл.
<script type="text/javascript">
var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
zip.generateAsync({type:"blob"})
.then(function(content) {
// see FileSaver.js
saveAs(content, "file.zip");
});
</script>
Это загрузит файл с именем file.zip. Вы можете прочитать здесь: http://www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library