入力フォームからBase64エンコードファイルデータを取得する


100

Firebugで調べている情報を取得できる基本的なHTMLフォームがあります。

私の唯一の問題は、サーバーに送信される前にファイルデータをbase64でエンコードしようとしていることです。データベースに保存するには、その形式である必要があります。

<input type="file" id="fileupload" />

そしてJavascript + jQueryで:

var file = $('#fileupload').attr("files")[0];

利用可能なjavascriptに基づいたいくつかの操作があります:.getAsBinary()、. getAsText()、. getAsTextURL

ただし、これらはいずれも、使用できない「文字」が含まれているため挿入できる使用可能なテキストを返しません。アップロードしたファイルで「ポストバック」が発生したくないので、特定のオブジェクトをターゲットとする複数のフォームを用意する必要があるため、重要です。この方法でファイルを取得し、JavaScriptを使用します。

広く入手可能なJavascript base64エンコーダの1つを使用できるようにファイルを取得するにはどうすればよいですか?

ありがとう

更新-ここから報奨金を開始します。クロスブラウザのサポートが必要です!!!

ここに私がいるところがあります:

<input type="file" id="fileuploadform" />

<script type="text/javascript">
var uploadformid = 'fileuploadform';
var uploadform = document.getElementById(uploadformid);


/* method to fetch and encode specific file here based on different browsers */

</script>

クロスブラウザーサポートに関するいくつかの問題:

var file = $j(fileUpload.toString()).attr('files')[0];
fileBody = file.getAsDataURL(); // only would works in Firefox

また、IEは以下をサポートしていません。

var file = $j(fileUpload.toString()).attr('files')[0];

だから私は次のものと置き換える必要があります:

var element = 'id';
var element = document.getElementById(id);

IEサポート用。

これは、Firefox、Chrome、Safariで機能します(ただし、ファイルを適切にエンコードしないか、少なくとも投稿後にファイルが正しく出力されません)

var file = $j(fileUpload.toString()).attr('files')[0];
var encoded = Btoa(file);

また、

file.readAsArrayBuffer() 

HTML5でのみサポートされているようですか?

多くの人が提案しました: http : //www.webtoolkit.info/javascript-base64.html

しかし、これは、base64エンコードする前にUTF_8メソッドでエラーを返すだけですか?(または空の文字列)

var encoded = Base64.encode(file); 

何をアップロードしていますか?テキストデータまたはバイナリ?
beatgammit 2011

@tjamensonバイナリデータ-本当に「ワードドキュメント」「pdf」「イメージ」など。ファイル名を別の変数に割り当てるつもりでしたが、何ができるのかを理解する上で致命的な欠陥があるのではないかと考え始めましたフォームとhtmlをアップロードします-この方法は完全に不可能であり、文字列として投稿することでファイルデータを送信することはできませんか?また、私が読んでいるHTML5がなければ、いくつかの解決策があります
jordan.baucke

面白い。ブラウザーとサーバーの間でbase-64エンコードを使用し、ブラウザーでこれを実現しようとしているのはなぜですか?データを保護しようとする場合、SSLはワイヤを介してすべてのHTTPデータ(ファイルを含む)を暗号化するため、はるかに簡単です。また、データベースに必要な場合は、サーバー側をbase-64にすることができます。
ウィリアムウォルセス

@William私はデータを保護するつもりはありません。正しい形式にしてください。Salesforce.com(Apexプラットフォーム)では、データベースにレコードを作成する前にデータベースをbase64でエンコードする必要があります。フォームを介してファイルデータbase64でエンコードする機能は、十分に文書化されていません(この質問をした後で、これを行う方法を理解しました)。とにかく、base64でエンコードされたバイナリファイルデータは、HTML5またはMozilla File APIで
jordan.baucke

1
OK、これでなぜこれが必要なのかわかりました。中間サーバーなし+クレイジークラウド要件+クロスブラウザーソリューションなし=混乱 ごめんなさい。
ウィリアムウォルセス

回答:


121

ブラウザ側のJavaScriptでは完全に可能です。

簡単な方法:

readAsDataURL()メソッドは、すでにあなたのためにbase64としてエンコードすることがあります。おそらく最初のもの(最初のものまで)を取り除く必要がありますが、それは大したことではありません。しかし、これはすべての楽しみを奪います。

難しい方法:

難しい方法で試す場合(または機能しない場合)は、を参照してくださいreadAsArrayBuffer()。これにより、Uint8Arrayが提供され、指定したメソッドを使用できます。これはおそらく、アップロードする前に画像データを操作したり、他のブードゥーマジックを行ったりするなど、データ自体をいじる場合にのみ役立ちます。

2つの方法があります。

  • 文字列に変換し、組み込みbtoaまたは類似のもの を使用します
    • 私はすべてのケースをテストしたわけではありませんが、私にとってはうまくいきます-文字コードを取得するだけです
  • Uint8Arrayからbase64に直接変換する

最近、ブラウザにtarを実装しました。そのプロセスの一部として、私は独自の直接Uint8Array-> base64実装を作成しました。私はあなたがそれを必要とするとは思わないが、あなたが調べたいならここにある。それはかなりきちんとしている。

私が今していること:

Uint8Arrayから文字列に変換するコードはかなり単純です(bufはUint8Arrayです)。

function uint8ToString(buf) {
    var i, length, out = '';
    for (i = 0, length = buf.length; i < length; i += 1) {
        out += String.fromCharCode(buf[i]);
    }
    return out;
}

そこから、次のようにします。

var base64 = btoa(uint8ToString(yourUint8Array));

Base64はbase64でエンコードされた文字列になり、桃色だけをアップロードするはずです。プッシュする前に再確認したい場合は、これを試してください:

window.open("data:application/octet-stream;base64," + base64);

ファイルとしてダウンロードされます。

他の情報:

データをUint8Arrayとして取得するには、MDNドキュメントをご覧ください。


素晴らしい- readAsArrayBuffer()正しいbase64データのように見えるものを出力すると思ったが、文字列の物乞いの部分が原因で処理されなかった-今すぐ試してみる!
jordan.baucke

1
readAsArrayBuffer()はChrome / Safariには存在しないようで、他のブラウザーで問題が発生すると想定しています。これらの他のブラウザーで使用できる同等のものはありますか?
jordan.baucke

createObjectURL()<-これは実装しようとする見込みがあるようですが、IEには3番目のホイールが必要になると思います
jordan.baucke

ダウンロードソリューションを実行する前にファイル名を割り当てることはできますか?
オメガ

@Ωmega-いいえ。バイナリストリームをダウンロードするだけです。ファイル名を指定する方法(AFAIK)はありません。一部のブラウザは拡張機能を推測します。ファイル名を取得するには、アップロードしてから再度ダウンロードする必要があります。
beatgammit 2013

37

私のソリューションは、使用したreadAsBinaryString()btoa()その結果に。

uploadFileToServer(event) {
    var file = event.srcElement.files[0];
    console.log(file);
    var reader = new FileReader();
    reader.readAsBinaryString(file);

    reader.onload = function() {
        console.log(btoa(reader.result));
    };
    reader.onerror = function() {
        console.log('there are some problems');
    };
}

3
はるかに簡単な方法で、なぜこれはより多くの票を持っていないのですか?
17

14

FileReaderを使用して、Ajaxリクエストを使用せずにファイルアップロードボタンをクリックしたときに画像を表示しました。以下は、誰かに役立つかもしれないというコードの希望です。

$(document).ready(function($) {
    $.extend( true, jQuery.fn, {        
        imagePreview: function( options ){          
            var defaults = {};
            if( options ){
                $.extend( true, defaults, options );
            }
            $.each( this, function(){
                var $this = $( this );              
                $this.bind( 'change', function( evt ){

                    var files = evt.target.files; // FileList object
                    // Loop through the FileList and render image files as thumbnails.
                    for (var i = 0, f; f = files[i]; i++) {
                        // Only process image files.
                        if (!f.type.match('image.*')) {
                        continue;
                        }
                        var reader = new FileReader();
                        // Closure to capture the file information.
                        reader.onload = (function(theFile) {
                            return function(e) {
                                // Render thumbnail.
                                    $('#imageURL').attr('src',e.target.result);                         
                            };
                        })(f);
                        // Read in the image file as a data URL.
                        reader.readAsDataURL(f);
                    }

                });
            });
        }   
    });
    $( '#fileinput' ).imagePreview();
});

1

私自身これに苦労した後、それをサポートするブラウザー(Chrome、Firefox、およびまだリリースされていないSafari 6)用のFileReader、およびPOSTされたファイルデータを他のBase64エンコードデータとしてエコーバックするPHPスクリプトを実装するようになりましたブラウザ。


0

Ajaxスタイルのアップロードに「iframe」を使用することは、HTML5が完全に普及し、アプリでレガシーブラウザーをサポートする必要がなくなるまで、私の状況にとってはるかに良い選択であると私は考え始めました!


興味があれば、[ webtoolkit.info/javascript-base64.html#]を使用してコメントアウトしinput = Base64._utf8_encode(input);てみoutput = Base64._utf8_decode(output);ませんか?utf-8変換エラー以外の問題はありますか?
shr

@shr各ブラウザでこれらのメソッドに入力するためのバイナリファイルデータを取得する方法がわかりません。$('#inputid').files[0]私が知る限り、IE7では機能しません)。それが簡単だったら?var output = Base64.encode($('#inputid').files[0])??
jordan.baucke 2011

0

@Josefの答えに触発されました:

const fileToBase64 = async (file) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = (e) => reject(e)
  })

const file = event.srcElement.files[0];
const imageStr = await fileToBase64(file)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.