14

私は、ユーザーが画像をアップロードできるようにするアプリケーション(Node.jsで、この場合は関係ありません)に取り組んでいます。input(type = "file")フィールドを持つフォームを使用すると正常に機能します。

ただし、代わりにHTML5のドラッグアンドドロップを使用して画像をアップロードできるようにする必要があります。私が来た限り、画像をクライアントにドラッグすることは可能であり、画像のサムネイルはdivに表示されます。ただし、ファイルのアップロードを機能させるには、本当に助けが必要です。

問題は、現在使用しているフォームを使用し、(どういうわけか)ファイルのパスを入力フィールドに渡すことです。つまり、フローは現在とまったく同じように機能しますが、参照してファイルを選択する代わりにドラッグアンドドロップで入力フィールドに添付したい。

以下のドラッグアンドドロップ用のjsコードでは、クライアントにドラッグされたファイルは変数「file」に格納されており、「file.name」、「file.type」、「file.size」を使用できます。以前からフォームを使用した場合とまったく同じように機能します。ただし、ファイルの「パス」(file.path)にアクセスできないため、以前と同じようにファイルサーバー側にアクセスしてアップロードすることができません。

問題は、ファイルがクライアントにドラッグされた後にファイルオブジェクトを入力フィールドに渡して、[送信]をクリックしてファイルをアップロードできるようにすることは可能ですか?もしそうなら、これはどのように行うことができますか?

前もって感謝します!

ドロップボックスと、ファイルのアップロードに使用しているフォーム:

<div id='upload'>
    <article>
        <div id='holder'>
            <p id='status'>File API and FileReader API not supported</p>
        </div>
    </article> 

    <form method='post' enctype='multipart/form-data' action='/file-upload'>
        <p>
            <input type='file' name='thumbnail'>
        </p>
        <p>
            <input type='submit'>
        </p>
    </form>
</div>

ドラッグアンドドロップのコード:

uploadImage: function(){
    var holder = document.getElementById('holder'),
        state = document.getElementById('status');

    if (typeof window.FileReader === 'undefined') {
      state.className = 'fail';
    } else {
      state.className = 'success';
      state.innerHTML = 'File API & FileReader available';
    }

    holder.ondragover = function () { this.className = 'hover'; return false; };

    holder.ondragend = function () { this.className = ''; return false; };

    holder.ondrop = function (e) {
      this.className = '';
      e.preventDefault();

      var file = e.dataTransfer.files[0],
          reader = new FileReader();

      reader.onload = function (event) {
        holder.style.background = 'url(' + event.target.result + ') no-repeat center';
      };

      reader.readAsDataURL(file);

      return false;
    };
},
4

3 に答える 3

8

ファイル入力を使用してファイルデータを追加することはできません。それでも、(他の技術の中でも)できることは、base64(readAsDataURLメソッドを使用する場合はreader.onloadイベントからevent.target.resultとしてネイティブに利用可能)でエンコードされたデータを使用し、それを非表示フィールドに配置することです。

html

<article>
    <div id='holder'>
        <p id='status'>File API and FileReader API not supported</p>
    </div>
</article> 

<form method='post' enctype='multipart/form-data' action='/file-upload'>
        <input type='file' name='thumbnail' />
        <input type='hidden' name='base64data' />
        <input type='submit' formenctype='application/x-www-form-urlencoded' />
</form>

js

reader = new FileReader();
reader.onload = function (event) {
    document.getElementById('base64data').setAttribute('value', event.target.result);
};
reader.readAsDataURL(file);

サーバー側からは、ファイルからbase64でエンコードされたデータを取得し、デコードして必要に応じて使用することができます。

フォームの送信中に、「enctype」属性を変更して(formenctype属性を介して実行)、基本的なhtmlファイル入力を削除することもできます。これは、データがテキストフィールドに投稿されるためです。

于 2012-10-07T23:44:30.960 に答える
0

コードビハインドでアクセスすると、reader.onload (@challet の回答を参照) に設定された隠しフィールドが設定されていないことがわかりました。asp.net と WebForms プロジェクトを使用しています。非表示のフィールドにアクセスするには、フィールド名の前に MainContent_ を追加する必要があります。aspxコードは以下です


<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
...
<script type="text/javascript">
    function dropHandler(ev) {
        alert("File(s) dropped");
        // Prevent default behavior (Prevent file from being opened)
        ev.preventDefault();
        //alert("Default prevented");
        if (ev.dataTransfer.items) {
            if (ev.dataTransfer.items.length > 1) {
                alert("Only single files can be dragged and dropped into Caption Pro Web");
                return;
            }
            // If dropped items aren't files, reject them
            if (ev.dataTransfer.items[0].kind === 'file') {
                var file = ev.dataTransfer.items[0].getAsFile();                    
                document.getElementById("MainContent_DroppedFileName").value = ev.dataTransfer.items[0].name
                reader = new FileReader();
                reader.onload = function (event) {
                    document.getElementById('MainContent_DroppedFileContent').value = event.target.result;
                };
                reader.readAsDataURL(ev.dataTransfer.items[0]);               
            }
        } else {
            // Use DataTransfer interface to access the file(s)
             if (ev.dataTransfer.files.length > 1) {
                alert("Only single files can be dragged and dropped into Caption Pro Web");
                return;
            }           
            document.getElementById("MainContent_DroppedFileName").value = ev.dataTransfer.files[0].name
            document.getElementById("MainContent_DroppedFileContent").value = "Test";

            reader = new FileReader();
            reader.onload = function (event) {
                 document.getElementById("MainContent_DroppedFileContent").value = event.target.result;
            };
            reader.readAsDataURL(ev.dataTransfer.files[0]);           
        }

        document.getElementById('<%=btnDrop.ClientID %>').click();

    }
</script>

...

    <div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);">
    <p>Drag image to this Drop Zone ...</p>
    </div> 
    <asp:HiddenField ID="DroppedFileName" runat="server" />
    <asp:HiddenField ID="DroppedFileContent" runat="server" />
...
 </asp:Content>

以下に示すように、C#から隠しフィールドにアクセスします

protected void btnDrop_Click(object sender, EventArgs e)
         {
             string FileName = DroppedFileName.Value;
             string FileContent = DroppedFileContent.Value;
         }

Internet Explorer をターゲット ブラウザーとして使用し (ドラッグ アンド ドロップが無効になるため、管理者として VS を実行していません)、reader.onload() 関数にブレークポイントを設定すると、隠しフィールド DroppedFileContent にエンコードされたファイル コンテンツが含まれますが、 btnDrop_Click からアクセスします。reader.onload() の前に設定された "Test" のみが含まれ、エンコードされたファイルのコンテンツは含まれません。フィールド DroppedFileNam.Value は Javascript で設定されています。

于 2019-09-25T03:33:50.127 に答える