私は最近WebGLをいじっていて、Colladaの読者が働いています。問題はそれがかなり遅いということです(Colladaは非常に冗長なフォーマットです)、それで私はファイルをより使いやすいフォーマット(おそらくJSON)に変換し始めるつもりです。 JavaScriptでファイルを解析するためのコードをすでに持っているので、私はそれを私のエクスポーターとしても使うことができます!問題は保存されています。
これで、ファイルを解析し、その結果をサーバーに送信し、ブラウザにダウンロードとしてサーバーからファイルを要求することができるようになりました。しかし、実際にはサーバーはこの特定のプロセスとは無関係です。目的のファイルの内容は既にメモリにあります。純粋なJavaScriptを使用してユーザーにダウンロードを提示する方法はありますか? (私はそれを疑います、しかし同様に尋ねるかもしれません...)
そして明確にするために:私はユーザーの知らないうちにファイルシステムにアクセスしようとしているのではありません!ユーザーは(おそらくドラッグアンドドロップで)ファイルを提供し、スクリプトはメモリ内のファイルを変換し、ユーザーは結果をダウンロードするように促されます。ブラウザに関する限り、これらすべては「安全な」活動であるべきです。
[編集]: 前もって言及しなかったので、 "Flash"と答えたポスターは十分に有効ですが、私がやっていることの一部は純粋なHTML5で何ができるかを強調するための試みです...だからFlashは私の中では正直です。場合。 (それは「本物の」Webアプリを使っている人には完全に有効な答えですが。)そういうわけで、私はサーバーを関与させたくない限り、私は運が悪くなっているようです。とにかくありがとう!
MatthewとDennksterがその選択肢を指摘してくれたおかげで、data:URIを作ることは間違いなく私にとってトリックです!これが基本的に私のやり方です:
1)すべてのコンテンツを「コンテンツ」と呼ばれる文字列にする(例えば、最初にそれを作成することによって、または既に構築されたページのタグのinnerHTMLを読み取ることによって)。
2)データURIを構築します。
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
ブラウザの種類などによっては長さに制限があります。 Firefox 3.6.12は少なくとも256kまで動作します。代わりにencodeURIComponentを使用してBase64でエンコードすると効率が良くなる可能性がありますが、私にとってはそれで問題ありませんでした。
3)新しいウィンドウを開き、このURIに「リダイレクト」すると、JavaScriptで生成されたページのダウンロード場所が求められます。
newWindow = window.open(uriContent, 'neuesDokument');
それでおしまい。
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は、Internet ExplorerをサポートするためにFileSaver.jsで使用されるnavigator.msSaveBlob(blob, filename)
メソッド( MSDN )をサポートしています。
私は ブログ投稿 を書き、この問題に関する詳細を書いています。
長いデータURIはブラウザのパフォーマンス上の問題を引き起こす可能性があります。クライアントサイドで生成されたファイルを保存するもう1つのオプションは、それらの内容をBlob(またはFile)オブジェクトに入れ、 URL.createObjectURL(blob)
を使用してダウンロードリンクを作成することです。これは、BLOBの内容を取得するために使用できるURLを返します。 BLOBは、URLでURL.revokeObjectURL()
が呼び出されるか、それを作成した文書が閉じられるまで、ブラウザ内に保存されます。ほとんどのウェブブラウザは でオブジェクトURLをサポートしています 、Opera Miniはそれらをサポートしていない唯一のものです。
データがテキストまたはイメージの場合、ブラウザはファイルをディスクに保存する代わりにそのファイルを開くことができます。リンクをクリックしたときにファイルがダウンロードされるようにするには、download
属性を使用できます。ただし、すべてのWebブラウザで がダウンロード属性 をサポートしているわけではありません。別のオプションは、ファイルのMIMEタイプとしてapplication/octet-stream
を使用することですが、これはファイルをバイナリBLOBとして表示させます。ファイル名を指定しない場合、または指定できない場合は特にユーザーに不便です。 ' HTMLでテキストリンクをクリックしてクリックすると、[名前を付けて保存...]ポップアップが強制的に開かれます 。
BLOBがFileコンストラクタで作成されている場合は、ファイル名を設定することもできますが、 のFileコンストラクタ をサポートしているWebブラウザはいくつかあります。ファイル名を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's 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>
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();
}
これを行うためのFlashベースのJavaScriptインターフェースであるDoug Neinerの Downloadify を見てください。
Downloadifyは、サーバーとのやり取りなしに、ブラウザ内でファイルの生成と保存を可能にする小さなJavaScript + Flashライブラリです。
<a download="My-FileName.txt" href="data:application/octet-stream,HELLO-WORLDDDDDDDD">Click here</a>
最近のすべてのブラウザで動作します。
私はFileSaver( https://github.com/eligrey/FileSaver.js )を使用しましたが、問題なく動作します。
例えば、ページに表示されているログをエクスポートするためにこの機能を実行しました。
あなたは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");
}
あなたは データURI を生成することができます。ただし、ブラウザ固有の制限があります。
私は自分に役立つ2つの簡単なアプローチを見つけました。まず、クリック済みのa
要素を使用してダウンロードデータを挿入します。そして次に、ダウンロードデータを使ってa
要素を生成し、a.click()
を実行してそれを削除します。しかし、2番目の方法は、ユーザーのクリック操作によっても呼び出される場合にのみ機能します。 (一部)ブラウザはロード時やタイムアウト(setTimeout)後にトリガされた場合など、他のコンテキストからclick()
をブロックします。
<!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>
ここにMathewが提案したデータのURIメソッドへのリンクがあります。これはsafariで動作しましたが、ファイルタイプを設定できなかったためうまくいきませんファイルを表示するには...
LocalStorageを使うことができます。これはHtml5に相当するクッキーです。 ChromeとFirefoxでは動作しますが、Firefoxでは動作します。サーバーにアップロードする必要がありました。つまり、自宅のコンピュータで直接テストしてもうまくいきませんでした。
私はHTML5の例を作り上げています。 http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html に移動して迷路をスクロールします。迷路を再構築するための情報はlocalStorageを使って保存されます。
私はこの記事に来て、xmlファイルをロードして作業するためのHTML5 JavaScriptを探しました。それは古いHTMLやJavaScriptと同じですか???
前述のように、 File API、 FileWriter および FileSystem APIを使用できます。ブラウザのタブ/ウィンドウのコンテキストからクライアントのマシンにファイルを保存します。
しかし、注意が必要な後者の2つのAPIに関するいくつかのことがあります。
これを行うために、直接的および間接的にAPIがどのように使用されるかの簡単な例を次に示します。
bakedGoods.get({
data: ["testFile"],
storageTypes: ["fileSystem"],
options: {fileSystem:{storageType: Window.PERSISTENT}},
complete: function(resultDataObj, byStorageTypeErrorObj){}
});
生のFile、FileWriter、およびFileSystem APIの使用
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);
FileSystemとFileWriterのAPIはもはや標準化されていませんが、私の意見では、それらの使用はいくつかのケースでは正当化できます。
「いくつかのケース」があなた自身のものを含むかどうかは、あなたが決めることです。
* BakedGoodsは、この男以外ではここで管理されていません。)
このスレッドは、バイナリファイルを生成する方法と指定されたファイルをダウンロードするためのプロンプトをすべてサーバーなしのクライアントコードで作成する方法を理解するのに非常に貴重でした。
私の最初のステップは、保存していたデータからバイナリBLOBを生成することでした。単一のバイナリ型に対してこれを行うためのサンプルはたくさんあります。私の場合は、BLOBを作成するための配列として渡すことができる複数の型を持つバイナリ形式があります。
saveAnimation: function() {
var device = this.Device;
var maxRow = ChromaAnimation.getMaxRow(device);
var maxColumn = ChromaAnimation.getMaxColumn(device);
var frames = this.Frames;
var frameCount = frames.length;
var writeArrays = [];
var writeArray = new Uint32Array(1);
var version = 1;
writeArray[0] = version;
writeArrays.Push(writeArray.buffer);
//console.log('version:', version);
var writeArray = new Uint8Array(1);
var deviceType = this.DeviceType;
writeArray[0] = deviceType;
writeArrays.Push(writeArray.buffer);
//console.log('deviceType:', deviceType);
var writeArray = new Uint8Array(1);
writeArray[0] = device;
writeArrays.Push(writeArray.buffer);
//console.log('device:', device);
var writeArray = new Uint32Array(1);
writeArray[0] = frameCount;
writeArrays.Push(writeArray.buffer);
//console.log('frameCount:', frameCount);
for (var index = 0; index < frameCount; ++index) {
var frame = frames[index];
var writeArray = new Float32Array(1);
var duration = frame.Duration;
if (duration < 0.033) {
duration = 0.033;
}
writeArray[0] = duration;
writeArrays.Push(writeArray.buffer);
//console.log('Frame', index, 'duration', duration);
var writeArray = new Uint32Array(maxRow * maxColumn);
for (var i = 0; i < maxRow; ++i) {
for (var j = 0; j < maxColumn; ++j) {
var color = frame.Colors[i][j];
writeArray[i * maxColumn + j] = color;
}
}
writeArrays.Push(writeArray.buffer);
}
var blob = new Blob(writeArrays, {type: 'application/octet-stream'});
return blob;
}
次のステップは、事前定義された名前でこのBLOBをダウンロードするようにユーザーにプロンプトを出すことです。
必要なのはHTML 5に追加した名前付きリンクだけで、これを使用して初期ファイル名の名前を変更できます。リンクは表示する必要がないので、非表示にしました。
<a id="lnkDownload" style="display: none" download="client.chroma" href="" target="_blank"></a>
最後のステップは、ファイルをダウンロードするようにユーザーに促すことです。
var data = animation.saveAnimation();
var uriContent = URL.createObjectURL(data);
var lnkDownload = document.getElementById('lnkDownload');
lnkDownload.download = 'theDefaultFileName.extension';
lnkDownload.href = uriContent;
lnkDownload.click();
これは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>
このコードをコピーすると、このコードはHello Worldという内容のファイルhello.txtを含むZipファイルをダウンロードします。すべてうまくいけば、これはファイルをダウンロードするでしょう。
<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
やってみる
let a = document.createElement('a');
a.href = "data:application/octet-stream,"+encodeURIComponent('"My DATA"');
a.download = 'myFile.json';
a.click();