[Javascript] ファイルを非同期でアップロードするにはどうすればよいですか?



Answers

jQueryのファイルアップロードには、様々な既製のプラグインがあります。

この種のハッキングをアップロードすることは楽しい経験ではないので、人々は既製のソリューションを楽しんでいます。

ここにはいくつかあります:

NPM(キーワードとして「jquery-plugin」を使用)またはGithubでさらに多くのプロジェクトを検索できます。

Question

jQueryと非同期でファイルをアップロードしたいと思います。 これは私のHTMLです:

<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

ここで私のJqueryコード:

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});

ファイルをアップロードする代わりに、ファイル名を取得するだけです。 この問題を解決するにはどうすればよいですか?

現在の解決策

私はファイルをアップロードするためにjQueryフォームプラグインを使用しています。




var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name="filename"]')[0].files[0]);

$.ajax({
    url:"page.php",
    data:formData,
    type: 'POST',
    dataType:"JSON",
    cache: false,
    contentType: false,
    processData: false,
    success:function(data){ }
});

フォームデータを使用して、画像を含むすべての値を投稿することができます。




この目的のために、 Fine Uploaderプラグインを使用することをお勧めします。 あなたのJavaScriptコードは次のようになります:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});



Look for Handling the upload process for a file, asynchronously in here: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

Sample from the link

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>



It is an old question, but still has no answer correct answer, so:

Have you tried jQuery-File-Upload ?

Here is an example from the link above -> jQuery-File-Upload that might solve your problem:

$('#fileupload').fileupload({
    add: function (e, data) {
        var that = this;
        $.getJSON('/example/url', function (result) {
            data.formData = result; // e.g. {id: 123}
            $.blueimp.fileupload.prototype
                .options.add.call(that, e, data);
        });
    } 
});



jQuery Uploadifyは、以前にファイルをアップロードするために使用したもう1つの良いプラグインです。 JavaScriptコードは次のように簡単です:コード。 ただし、Internet Explorerでは新しいバージョンが動作しません。

$('#file_upload').uploadify({
    'swf': '/public/js/uploadify.swf',
    'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
    'cancelImg': '/public/images/uploadify-cancel.png',
    'multi': true,
    'onQueueComplete': function (queueData) {
        // ...
    },
    'onUploadStart': function (file) {
        // ...
    }
});

私は多くの検索を行いましたが、プラグインなしでファイルをアップロードするための別の解決方法がありました。 解決策は次のとおりです。

$(document).ready(function () {
    $('#btn_Upload').live('click', AjaxFileUpload);
});

function AjaxFileUpload() {
    var fileInput = document.getElementById("#Uploader");
    var file = fileInput.files[0];
    var fd = new FormData();
    fd.append("files", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'Uploader.ashx');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
            alert('error');
    };
    xhr.send(fd);
}



Convert file to base64 using |HTML5's readAsDataURL() or some base64 encoder . ここでフィドル

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

次に検索する:

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



私はこれをRails環境で書いています 。 軽量のjQuery形式のプラグインを使用する場合は、わずか5行分のJavaScriptしかありません。

remote_form_forの標準が複数の部分からなるフォームの提出を理解していないため、AJAXアップロードをremote_form_forすることが課題です。 RailsがAJAXリクエストで取り戻すファイル・データを送信することはありません。

それがjQuery形式のプラグインです。

これはRailsのコードです:

<% remote_form_for(:image_form, 
                   :url => { :controller => "blogs", :action => :create_asset }, 
                   :html => { :method => :post, 
                              :id => 'uploadForm', :multipart => true }) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

関連するJavaScriptは次のとおりです。

$('#uploadForm input').change(function(){
 $(this).parent().ajaxSubmit({
  beforeSubmit: function(a,f,o) {
   o.dataType = 'json';
  },
  complete: function(XMLHttpRequest, textStatus) {
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  },
 });
});

そして、ここにRailsコントローラのアクション、かなりのバニラがあります:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

私は過去数週間、Bloggityでこれを使ってきました。それはチャンピオンのように働いています。




これまで私がこれまで行ってきた最もシンプルでロバストな方法は、フォームで非表示のiFrameタグをターゲットに設定することです。ページをリロードせずにiframe内で送信します。

つまり、プラグイン、JavaScript、またはHTML以外の他の形式の「マジック」を使用したくない場合です。 もちろん、これをJavaScriptと組み合わせることもできますし、何がありますか...

<form target="iframe" action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

<iframe name="iframe" id="iframe" style="display:none" ></iframe>

iframe onLoad内容を読み込んでサーバーのエラーや成功の応答を確認し、その結果をユーザーに出力することもできます。

Chrome、iFrame、onLoad

注 - アップロード/ダウンロードを行うときにUIブロッカーを設定する方法に興味がある場合は、読んでおく必要があります

現在のところ、Chromeはファイルを転送する際にiframeのonLoadイベントをトリガーしません。 Firefox、IE、およびEdgeはすべて、ファイル転送のためにonloadイベントを発生させます。

私が見つけた唯一の解決策は、クッキーを使用することでした。

アップロード/ダウンロードが開始されたときに基本的にそれを行うには:

  • [クライアント側]クッキーの存在を探す間隔を開始する
  • [サーバー側]ファイルデータに必要な処理を行います
  • [サーバー側]クライアント側の間隔でCookieを設定する
  • [Client Side] Intervalはクッキーを見て、それをonLoadイベントのように使います。 たとえば、UIブロックを開始してからonLoad(またはCookieが作成されたとき)で、UIブロッカーを削除することができます。

このためにクッキーを使用するのは醜いですが、動作します。

ダウンロード時にこの問題を処理するjQueryプラグインを作成しました。ここで見つけることができます

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/jQuery-Plugins/iDownloader.js

同様の基本原理がアップロードにも適用されます。

ダウンローダを使用するには(JSを含む、明らかに)

 $('body').iDownloader({
     "onComplete" : function(){
          $('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
     }
 });

 $('somebuttion').click( function(){
      $('#uiBlocker').css('display', 'block'); //block the UI
      $('body').iDownloader('download', 'htttp://example.com/location/of/download');
 });

そして、サーバー側では、ファイルデータを転送する直前に、クッキーを作成します

 setcookie('iDownloader', true, time() + 30, "/");

プラグインはCookieを表示してから、 onCompleteコールバックをトリガーします。




Sample: If you use jQuery, you can do easy to an upload file. This is a small and strong jQuery plugin, http://jquery.malsup.com/form/ .

var $bar   = $('.ProgressBar');
$('.Form').ajaxForm({
  dataType: 'json',

  beforeSend: function(xhr) {
    var percentVal = '0%';
    $bar.width(percentVal);
  },

  uploadProgress: function(event, position, total, percentComplete) {
    var percentVal = percentComplete + '%';
    $bar.width(percentVal)
  },

  success: function(response) {
    // Response
  }
});

I hope it would be helpful




私はうまく動作するイメージをアップロードするために、以下のスクリプトを使用しています。

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

説明

私は、レスポンスdivを使用して、アップロードが完了した後にアップロードアニメーションとレスポンスを表示します。

最も重要なのは、このスクリプトを使用するときに、ファイルにidsなどの余分なデータを送信できることです。 私はスクリプトのようにextra-dataを言及しています。

PHPレベルでは、これは通常のファイルアップロードとして機能します。 余分なデータは$_POSTデータとして取り出すことができます。

ここでは、プラグインやものを使用していません。 コードは必要に応じて変更できます。 あなたはここで盲目的にコーディングしていません。 これは、jQueryファイルアップロードのコア機能です。 実際にはJavascript。




このAJAXファイルのアップロードjQueryプラグインはsomehwereファイルをアップロードし、その応答をコールバックに渡します。

  • 特定のHTMLには依存しません。単に<input type="file">
  • サーバーが特定の方法で応答する必要はありません
  • 使用しているファイルの数やページ上の場所は関係ありません

- 少しでも使う -

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

- またはそれと同じくらい -

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});



jQuery .ajax()簡単にアップロードできます。

HTML:

<form id="upload-form">
    <div>
        <label for="file">File:</label>
        <input type="file" id="file" name="file" />
        <progress class="progress" value="0" max="100"></progress>
    </div>
    <hr />
    <input type="submit" value="Submit" />
</form>

CSS

.progress { display: none; }

Javascript:

$(document).ready(function(ev) {
    $("#upload-form").on('submit', (function(ev) {
        ev.preventDefault();
        $.ajax({
            xhr: function() {
                var progress = $('.progress'),
                    xhr = $.ajaxSettings.xhr();

                progress.show();

                xhr.upload.onprogress = function(ev) {
                    if (ev.lengthComputable) {
                        var percentComplete = parseInt((ev.loaded / ev.total) * 100);
                        progress.val(percentComplete);
                        if (percentComplete === 100) {
                            progress.hide().val(0);
                        }
                    }
                };

                return xhr;
            },
            url: 'upload.php',
            type: 'POST',
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(data, status, xhr) {
                // ...
            },
            error: function(xhr, status, error) {
                // ...
            }
       });
    }));
});



Links