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


2914

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: ");
            }
        });
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

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


jQueryのファイルアップロードを実行するためのさまざまな既成のプラグインがあります。この種のアップロードハックは楽しい体験ではないため、既成のソリューションを使用することを楽しんでいます。ここではいくつかあります: - jQueryのファイルアップローダ - 複数ファイルのアップロードプラグイン - ミニ複数ファイルのアップロード - jQueryのファイルアップロードあなたは(キーワードとして「jqueryの-プラグイン」を使用して)NPM上の複数のプロジェクトのためか、Githubの上で検索することができます。
陽気な

72
var filenameが$( '#file')の値を取得しているため、ファイル名のみが取得され、入力にあるファイルは取得されません
Jimmy

21
ここに良いものがあります:http : //blueimp.github.io/jQuery-File-Upload/-HTML5 ajaxアップロード-サポートされていないブラウザーのiframeへの適切なフォールバック-マルチファイル非同期アップロード (ドキュメントはこちら
Ashish Panery 2013

3
これも確認してください:stackoverflow.com/questions/6974684/…、ここではjQueryを介してそれを達成する方法について説明しています
Chococroc

2
@Jimmy代わりに、入力にあるファイルをどのように取得しますか?
アレックス、2014

回答:


2519

ではHTML5あなたはAjaxとjQueryを使ってファイルのアップロードを行うことができます。それだけでなく、ファイルの検証(名前、サイズ、MIMEタイプ)を実行したり、HTML5進捗タグ(またはdiv)を使用して進捗イベントを処理したりできます。最近、ファイルアップローダーを作成する必要がありましたが、Flashを使用たくありませんでしたもIframesもプラグインも、いくつかの調査の結果、解決策を思いつきました。

HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

最初に、必要に応じて検証を行うことができます。たとえば.on('change')、ファイルの場合:

$(':file').on('change', function () {
  var file = this.files[0];

  if (file.size > 1024) {
    alert('max upload size is 1k');
  }

  // Also see .name, .type
});

次に、$.ajax()ボタンをクリックするだけで送信します。

$(':button').on('click', function () {
  $.ajax({
    // Your server script to process the upload
    url: 'upload.php',
    type: 'POST',

    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    // Custom XMLHttpRequest
    xhr: function () {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        // For handling the progress of the upload
        myXhr.upload.addEventListener('progress', function (e) {
          if (e.lengthComputable) {
            $('progress').attr({
              value: e.loaded,
              max: e.total,
            });
          }
        }, false);
      }
      return myXhr;
    }
  });
});

ご覧のとおり、HTML5(およびいくつかの調査)を使用すると、ファイルのアップロードが可能になるだけでなく、非常に簡単になります。例のHTML5コンポーネントの一部はすべてのブラウザーで利用できるわけではないので、Google Chromeで試してください。


14
次に、upload.phpで$ _FILESを使用できますか?
アレッサンドロコセンティーノ

71
これはInternet Explorerで機能しますが、バージョン10(caniuse.com/xhr2)でのみ機能します
Tyler

18
こんにちは、私はPHPがあなたの選択した言語に感謝します...しかし、これがASP.NET MVCでも機能するかどうかを知っていますか?私は.NET開発者であり、AJAXファイルのアップロードを行うために簡単な例を利用しようとしましたが、サーバー側では、AJAX経由で投稿したファイルを取得できません。最新のChromeを使用しています。
Shumii 2013年

25
ここですべての魔法を行うのはFormDataです。これらのドキュメントを必ず確認してください。複数のファイルとフィールドに関するすべての質問が含まれています。
転生

4
ちょうど誰か他の人が時間を費やさないように... PHPで(そしておそらく他の場所で)データを使用する場合name="file"、これは<input>ファイルタグで非常に重要です。JavaScriptを使用して動的にフォームを作成したので、name属性は必要ありませんでしたが、データをサーバー側で取得するために絶対に必要な難しい方法を見つけました。
Kivak Wolf 2015

273

2019 Update:それはまだあなたのブラウザに依存します人口統計が使用。

「新しい」HTML5 fileAPIで理解する重要なことは、IE 10までサポートされなかったことです。です。あなたが狙っている特定の市場が古いバージョンのWindowsに向く傾向が平均よりも高い場合、その市場にアクセスできない可能性があります。

2017年の時点で、ブラウザーの約5%がIE 6、7、8、または9のいずれかです。大企業(たとえば、これがB2Bツール、またはトレーニングのために提供しているもの)に向かった場合、その数は急上昇する可能性があります。2016年に、私は彼らのマシンの60%以上でIE8を使用している会社と取引しました。

この編集の時点で、私の最初の回答からほぼ11年後の2019年です。IE9以下は世界的にで1%前後ですが、それでも使用率の高いクラスターが存在します。

これから重要なポイントは、機能に関係なくユーザーが使用しているブラウザを確認することです。そうでない場合は、「私にとってはうまくいく」がクライアントへの成果物として十分ではない理由について、素早く苦痛なレッスンを学びます。使ってもいいですかは便利なツールですが、人口統計をどこから取得しているかに注意してください。それらはあなたのものと一致しないかもしれません。これはエンタープライズ環境よりも真実ではありません。

2008年の私の回答は次のとおりです。


ただし、ファイルのアップロードには、実行可能な非JSメソッドがあります。(CSSで非表示にする)ページ上にiframeを作成し、フォームをターゲットにしてそのiframeに投稿できます。メインページを移動する必要はありません。

これは「本物の」投稿なので、完全にインタラクティブではありません。ステータスが必要な場合は、それを処理するためにサーバー側に何かが必要です。これはサーバーによって大きく異なります。ASP.NETには、より優れたメカニズムがあります。PHPプレーンは失敗しますが、Perlを使用できますまたはApacheの変更をして回避できます。

複数のファイルのアップロードが必要な場合は、各ファイルを1つずつ実行することをお勧めします(最大ファイルアップロード制限を超えるため)。最初のフォームをiframeにポストし、上記を使用して進行状況を監視し、完了したら、2番目のフォームをiframeにポストします。

または、Java / Flashソリューションを使用します。彼らは自分の投稿で何ができるかについてはるかに柔軟です...


142
-ブラウザがファイルのAPIをサポートしている場合、それは純粋なAJAXファイルのアップロードを行うできるようになりましたレコードのdeveloper.mozilla.org/en/using_files_from_web_applications
meleyal

iframeソリューションは非常にシンプルで簡単に機能します
Matthew Lock

これはかなり古い回答ですが、少し誤解を招くものでした。IEはIE7まではネイティブでXHRをサポートし、IE5まではActiveXを介してサポートしていました。w3schools.com/ajax/ajax_xmlhttprequest_create.asp。これを行う実際的な方法は、確かにフラッシュ(shockwave)コンポーネントを対象にするか、フラッシュ/ ActiveX(Silverlight)コントロールをロールアウトすることでした。JavaScriptを介してリクエストを発信し、応答を処理できる場合、それはajaxです。ただし、ajaxはxhrと同義ですが、それ自体はペイロードを配信/交換する下線のメカニズム/コンポーネントについては説明していません。
Brett Caswell、2015年

4
@BrettCaswell私は、AJAX / XHRが不可能であるとは言っていませんでした。それは、古いバージョンのIEのファイルにそれらを一緒に投稿することは不可能だったということです。それは完全に真実であり、現在もそうです。
オリ

これは方法ではありません、これはUXの意見です-多分それは有効です。
Nimjox

112

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

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

JSONを使用しているため、PHPの古いバージョンでは使用できません。
ロレンツォマヌッチ

Ajaxファイルアップロードよりもはるかにクリーンなようですが、いまいましいものを使用するためだけに膨大なコードを含める必要があります。
ripper234


35
「このプラグインは、GNU GPL 2以降およびGNU LGPL 2以降でオープンソース化されています。」そのため、コピーまたは変更されたバージョンを配布しない限り、プロジェクトを開く必要はありません。
Trantor Liu

何か不足していますか?このライブラリはもはやjqueryを使用していないようで、答えの構文をサポートしていませんか?
James McCormack

102

注:この回答は古くなっており、XHRを使用してファイルをアップロードできるようになりました。


XMLHttpRequest(Ajax)を使用してファイルをアップロードすることはできません。iframeまたはFlashを使用して効果をシミュレートできます。効果を得るためにiframe経由でファイルを送信する優れたjQueryフォームプラグイン


1
はい、iframeにPOSTして、そこでファイルをキャプチャできます。私はこれに関して非常に限られた経験しか持っていないので、私はそれについて本当にコメントすることはできません。
Mattias、

15
小さな発言:chromeとfirefoxの最新バージョンでは可能です。stackoverflow.com
questions / 4856917 /…

IE9
以前

96

今後の読者のためにまとめます。

非同期ファイルのアップロード

HTML5を使用

FormDataFile APIがサポートされている場合(両方のHTML5機能)、メソッドを使用してjQueryでファイルアップロードできます。$.ajax()

FormDataなしでファイル送信することもできますが、XMLHttpRequest(Ajax)で送信できるようにファイルを処理するには、File APIが存在する必要があります。

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

簡単で純粋なJavaScript(jQueryなし)の例については、「FormDataオブジェクトを使用したファイルの送信参照してください。

後退する

HTML5がサポートされていない(File APIがない)場合、他の純粋なJavaScriptソリューション(Flashや他のブラウザープラグインはありません)は非表示のiframeテクニックのみで、XMLHttpRequestオブジェクトを使用せずに非同期リクエストをエミュレートできます。

これは、ファイル入力を持つフォームのターゲットとしてiframeを設定することで構成されます。ユーザーがリクエストを送信するとファイルがアップロードされますが、レスポンスはメインページを再レンダリングする代わりにiframe内に表示されます。iframeを非表示にすると、プロセス全体がユーザーに透過的になり、非同期要求がエミュレートされます。

適切に実行すれば、どのブラウザーでも事実上機能するはずですが、iframeから応答を取得する方法としていくつかの注意点があります。

この場合、次のようなラッパープラグインを使用することを好むかもしれビフレスト使用していますインラインフレーム技術をも提供してjQueryのAjaxの輸送できるようにファイルを送信するだけで$.ajax()、このような方法を:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

プラグイン

BifröstはjQueryのajaxメソッドにフォールバックサポートを追加する小さなラッパーですが、jQueryフォームプラグインjQueryファイルアップロードなどの前述のプラグインの多くには、HTML5からさまざまなフォールバックまでのスタック全体と、プロセスを容易にするいくつかの便利な機能が含まれています。ニーズと要件に応じて、ベアインプリメンテーションまたはこのプラグインのいずれかを検討することができます。


3
ドキュメントに基づいて、注意する必要がある1つ:も送信する必要がありますcontentType: false。これをChromeで送信しなかった場合、フォームのコンテンツタイプはjQueryによって無効にされました。
2015

いい答えだ。改善のためのいくつかの提案:.done().fail()コールバックなど、回答に関係のないコードの部分を削除します。また、使用しない例FormDataとpro / consのリストは素晴らしいでしょう。
Zero3、2015

私はこのエラーを受け取りました:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
キャンドルジャック

85

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

  • 特定の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');
  }
});

1
@ user840250 jQuery 1.9.1?
ジョーダンフェルドシュタイン2013年

62

私は以下のスクリプトを使用して、たまたま問題なく画像をアップロードしています。

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アップロードのアニメーションとアップロードが完了した後のを示すために、。

最良の部分は、このスクリプトを使用するときに、IDなどの追加データをファイルと一緒に送信できることです。私はそれextra-dataをスクリプトのように述べました。

PHPレベルでは、これは通常のファイルアップロードとして機能します。追加データはデータとして取得でき$_POSTます。

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


5
-1は、jQueryを使用し、セレクターエンジンとイベントハンドラーを使用しない場合。addEventListenerクロスブラウザではありません。
マーク・

3
それは、ほんの少しの変更で、ほとんどこれに基づいている別の回答を追加することは無意味だからです。代わりに、この答えを修正する必要があります。
マーク

2
@RainFromHeaven、どうぞ、あなたは答えを編集できますか?クロスブラウザの方法でそれを行う方法がわかりません。
チアゴ・ネグリ

2
それでもIE 9以下では機能しません。多くのユーザーがまだこれらのバージョンのIEを使用しています。
Pierre

1
誰かがこれをasp.netで機能させる方法を説明できますか?webmethodを使用しますか?はいの場合、どのように見えますか?
SamuraiJack

49

バニラJavaScriptでそれをかなり簡単に行うことができます。これが私の現在のプロジェクトのスニペットです:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);

3
@ゲイリー:申し訳ありませんが、私もそのビットを投稿する必要がありました。HTML5の新しいドラッグアンドドロップ機能を使用していただけです。例はhtml5demos.com/file-api#view-sourceにあります。「ソースを表示」をクリックするだけです。基本的に、ondropイベント内でできることvar file = e.dataTransfer.files[0]
mpen

おそらく質問はその後編集されたかもしれませんが、私が開いたレッツディスカッションの一部の人々は、OPがjQueryソリューション(存在する場合)を要求し、そのような回答が別の質問に属している場合、バニラJS回答はトピックから外れていると思います。
アンディ

4
@Andyええと、私は同意しません、そして他の34人もそうです。jQueryを使用できる場合は、JavaScriptを使用できます。いずれにせよ、これはコミュニティサイトです。私がここで手助けしようとしているのはOPだけではありません。誰もが好きな答えを自由に選択/使用できます。一部の人々は、実際には追加のライブラリのオーバーヘッドがまったく必要ないのに、コード行がはるかに簡単/少ないと思うので、jQueryに引き付けられるだけです。
mpen 2017年

47

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) {
                // ...
            }
       });
    }));
});

1
@RaydenBlackのみjQuery。
Zayn Ali

アップロードの進行状況を取得する方法?
Ali Sherafat

44

過去に私がこれを行った最も単純で最も堅牢な方法は、フォームで非表示の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>

onLoadサーバーのエラーまたは成功の応答についてiframeの内容を読み取り、それをユーザーに出力することもできます。

Chrome、iFrame、およびonLoad

-注-アップロード/ダウンロードを行うときにUIブロッカーを設定する方法に興味がある場合にのみ読み続ける必要があります

現在、Chromeは、ファイルの転送に使用されている場合、iframeのonLoadイベントをトリガーしません。Firefox、IE、およびEdgeはすべて、ファイル転送のonloadイベントを起動します。

Chromeで機能することがわかった唯一の解決策は、Cookieを使用することでした。

基本的にアップロード/ダウンロードの開始時にそれを行うには:

  • [クライアント側] cookieの存在を探すための間隔を開始します
  • [サーバー側]ファイルデータに対して必要なことをすべて実行します
  • [サーバー側]クライアント側の間隔にCookieを設定します
  • [クライアント側] IntervalはCookieを確認し、onLoadイベントのように使用します。たとえば、UIブロッカーを起動してから、onLoadを(またはCookieが作成されたときに)UIブロッカーを削除できます。

これにcookieを使用することは醜いですが、機能します。

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

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/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');
 });

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

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

プラグインはCookieを確認し、onCompleteコールバックをトリガーします。


3
大好きです。誰かだけがこの素晴らしいソリューションの潜在的な問題に言及できたとしたら。解決策があるときに人々がなぜこれらの不格好なライブラリとプラグインを書いて使用するのか本当に理解できません。
Yevgeniy Afanasyev 2015年

1
ええと、その理由は、アップロード中にいくつかの進捗情報を表示するためだと思います。
Prakhar Mishra

32

私が見つけた解決策は、<form>ターゲットを非表示のiFrameにすることでした。次に、iFrameはJSを実行して、完了したことを(ページの読み込み時に)ユーザーに表示できます。


1
この回答に興味があります。リンクできるデモはありますか?
lfender6445 2015年

32

これをRails環境で記述しました。軽量のjQuery-formプラグインを使用すると、JavaScriptは約5行で済みます。

課題は、AJAXアップロードを標準として機能させることです remote_form_forはマルチパートフォームの送信を理解できないため。RailsがAJAXリクエストでシークするファイルデータは送信されません。

そこで登場するのがjQuery-formプラグインです。

そのための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でこれを使用してきました。


31

単純なAjaxアップローダーは別のオプションです。

https://github.com/LPology/Simple-Ajax-Uploader

  • クロスブラウザ-IE7 +、Firefox、Chrome、Safari、Operaで動作します
  • HTML5以外のブラウザーでも、複数の同時アップロードをサポート
  • フラッシュまたは外部CSSなし-1つの5Kb JavaScriptファイル
  • 完全なクロスブラウザープログレスバーのオプションの組み込みサポート(PHPのAPC拡張を使用)
  • 柔軟で高度にカスタマイズ可能-アップロードボタンとして任意の要素を使用し、独自の進行状況インジケーターをスタイル設定します
  • フォームは不要で、アップロードボタンとして機能する要素を提供するだけです
  • MITライセンス-商用プロジェクトで無料で使用できます

使用例:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});

2
これは、これまでで最も有望なようIE7+です。今それを試してみてください。ありがとう
ピエール14年

25

jQuery Uploadifyは、以前ファイルをアップロードするために使用した優れたプラグインです。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) {
        // ...
    }
});

私は多くの検索を行い、プラグインなしでajaxのみでファイルをアップロードするための別のソリューションを見つけました。解決策は次のとおりです。

$(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);
}

2
Uploadifyは何年も前から死んでいます。サポートまたは保守されなくなりました。
レイニコルス16年

24

これは、ファイルをアップロードする方法の別の解決策です(プラグインなし

単純なJavaScriptAJAXの使用(進行状況バー付き)

HTML部分

<form id="upload_form" enctype="multipart/form-data" method="post">
    <input type="file" name="file1" id="file1"><br>
    <input type="button" value="Upload File" onclick="uploadFile()">
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
    <h3 id="status"></h3>
    <p id="loaded_n_total"></p>
</form>

JSパート

function _(el){
    return document.getElementById(el);
}
function uploadFile(){
    var file = _("file1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("file1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
    _("status").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
    _("status").innerHTML = "Upload Aborted";
}

PHPの部分

<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
    echo "$fileName upload is complete";
} else {
    echo "move_uploaded_file function failed";
}
?>

これがEXAMPLEアプリケーションです


19
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){ }
});

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


6
注:キャッシュしないcache: falseため、POSTリクエストでは冗長です。POST
コーディングを行った

@Vivek Aasaithambi、私はこのエラーを受け取りました:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
キャンドルジャック

15

Jqueryで非同期にファイルをアップロードするには、以下の手順を使用します:

ステップ1プロジェクトでNugetマネージャーを開き、パッケージを追加します(jquery fileupload(検索ボックスに書き込む必要があるだけで、それが表示されてインストールされます))URL:https : //github.com/blueimp/jQuery-File-アップロードする

ステップ2以下のスクリプトをHTMLファイルに追加します。これらのスクリプトは、上記のパッケージを実行してプロジェクトにすでに追加されています。

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

ステップ3 以下のコードに従ってファイルアップロードコントロールを記述します。

<input id="upload" name="upload" type="file" />

ステップ4 jsメソッドを次のようにuploadFileとして記述します。

 function uploadFile(element) {

            $(element).fileupload({

                dataType: 'json',
                url: '../DocumentUpload/upload',
                autoUpload: true,
                add: function (e, data) {           
                  // write code for implementing, while selecting a file. 
                  // data represents the file data. 
                  //below code triggers the action in mvc controller
                  data.formData =
                                    {
                                     files: data.files[0]
                                    };
                  data.submit();
                },
                done: function (e, data) {          
                   // after file uploaded
                },
                progress: function (e, data) {

                   // progress
                },
                fail: function (e, data) {

                   //fail operation
                },
                stop: function () {

                  code for cancel operation
                }
            });

        };

ステップ5以下のように、準備が整った関数呼び出し要素ファイルのアップロードでプロセスを開始します。

$(document).ready(function()
{
    uploadFile($('#upload'));

});

ステップ6以下のようにMVCコントローラーとアクションを記述します。

public class DocumentUploadController : Controller
    {       

        [System.Web.Mvc.HttpPost]
        public JsonResult upload(ICollection<HttpPostedFileBase> files)
        {
            bool result = false;

            if (files != null || files.Count > 0)
            {
                try
                {
                    foreach (HttpPostedFileBase file in files)
                    {
                        if (file.ContentLength == 0)
                            throw new Exception("Zero length file!");                       
                        else 
                            //code for saving a file

                    }
                }
                catch (Exception)
                {
                    result = false;
                }
            }


            return new JsonResult()
                {
                    Data=result
                };


        }

    }

14

Jqueryを使用しない最新のアプローチは、ユーザーがファイルを選択したときに取得したFileListオブジェクトを使用し、Fetch<input type="file">使用してFormDataオブジェクトにラップされたFileListをポストすることです。

// The input DOM element // <input type="file">
const inputElement = document.querySelector('input[type=file]');

// Listen for a file submit from user
inputElement.addEventListener('change', () => {
    const data = new FormData();
    data.append('file', inputElement.files[0]);
    data.append('imageName', 'flower');

    // You can then post it to your server.
    // Fetch can accept an object of type FormData on its  body
    fetch('/uploadImage', {
        method: 'POST',
        body: data
    });
});

IEではサポートされていないようです
Marco Demaio

11

ここでは、フォームファイルをプレビューしてサーバーに送信できるデモが動作する解決済みのソリューションを確認できます。あなたのケースでは、サーバーへのファイルのアップロードを容易にするためにAjaxを使用する必要があります:

<from action="" id="formContent" method="post" enctype="multipart/form-data">
    <span>File</span>
    <input type="file" id="file" name="file" size="10"/>
    <input id="uploadbutton" type="button" value="Upload"/>
</form>

送信されるデータはフォームデータです。jQueryで、ボタンクリックの代わりにフォーム送信関数を使用して、以下に示すようにフォームファイルを送信します。

$(document).ready(function () {
   $("#formContent").submit(function(e){

     e.preventDefault();
     var formdata = new FormData(this);

 $.ajax({
     url: "ajax_upload_image.php",
     type: "POST",
     data: formdata,
     mimeTypes:"multipart/form-data",
     contentType: false,
     cache: false,
     processData: false,
     success: function(){

     alert("successfully submitted");

     });
   });
});

詳細を表示


11

サンプル:jQueryを使用すると、ファイルを簡単にアップロードできます。これは小さくて強力なjQueryプラグインです。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
  }
});

お役に立てれば幸いです


10

使用できます

$(function() {
    $("#file_upload_1").uploadify({
        height        : 30,
        swf           : '/uploadify/uploadify.swf',
        uploader      : '/uploadify/uploadify.php',
        width         : 120
    });
});

デモ


9

| HTML5のreadAsDataURL()またはいくつかのbase64エンコーダーを使用して、ファイルをbase64に変換します。 ここをいじる

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);

9

XMLHttpRequestを使用して非同期アップロードを行う際に、追加のパラメーターをファイル名と共に渡すことができます(flashおよびiframeの依存関係はありません)。追加のパラメーター値をFormDataに追加し、アップロードリクエストを送信します。


var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2'); 
formData.append('file', $('input[type=file]')[0].files[0]);

$.ajax({
    url: 'post back url',
    data: formData,
// other attributes of AJAX
});

また、Syncfusion JavaScript UIファイルのアップロードは、イベント引数を使用するだけでこのシナリオのソリューションを提供します。ここにドキュメントがあり、このコントロールの詳細についてはここにリンクの説明をここに入力してください


8

ここで非同期ファイルのアップロードプロセス処理するを探します。 https //developer.mozilla.org/en-US/docs/Using_files_from_web_applications

リンクからのサンプル

<?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>

7

これが私の解決策です。

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

そしてjs

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

コントローラ

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    [...]
}

2
あなたはあなたの答えにある種のフレームワークを混ぜたようです。少なくとも、回答がどのフレームワークに使用できるかについて言及する必要があります。さらに良いことに、すべてのフレームワークを削除し、提示された質問に対する回答のみを提示します。
Zero3、2015

2
それで、実際には「mvc」と呼ばれるmvcフレームワークがありますか?そしてそれはcsharpish構文を使用しますか?それは残酷です。
ノンチップ、2016年

6

HTML5JavaScriptを使用し、非同期でアップロードするのは非常に簡単です。アップロードロジックをhtmlとともに作成します。これは、apiが必要なため完全には機能しません/uploadが、ウェブサイトのルートからエンドポイントが呼び出された場合の動作を示します。このコードはあなたのために働くはずです:

const asyncFileUpload = () => {
  const fileInput = document.getElementById("file");
  const file = fileInput.files[0];
  const uri = "/upload";
  const xhr = new XMLHttpRequest();
  xhr.upload.onprogress = e => {
    const percentage = e.loaded / e.total;
    console.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("file uploaded");
    }
  };
  xhr.open("POST", uri, true);
  xhr.setRequestHeader("X-FileName", file.name);
  xhr.send(file);
}
<form>
  <span>File</span>
  <input type="file" id="file" name="file" size="10" />
  <input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>

また、XMLHttpRequesに関するいくつかの詳細情報:

XMLHttpRequestオブジェクト

最新のブラウザはすべてXMLHttpRequestオブジェクトをサポートしています。XMLHttpRequestオブジェクトを使用すると、舞台裏でWebサーバーとデータを交換できます。これは、ページ全体をリロードすることなく、Webページの一部を更新できることを意味します。


XMLHttpRequestオブジェクトを作成する

最近のすべてのブラウザー(Chrome、Firefox、IE7 +、Edge、Safari、Opera)には、XMLHttpRequestオブジェクトが組み込まれています。

XMLHttpRequestオブジェクトを作成するための構文:

変数=新しいXMLHttpRequest();


ドメイン間のアクセス

セキュリティ上の理由から、最新のブラウザではドメイン間のアクセスが許可されていません。

これは、WebページとそれがロードしようとするXMLファイルの両方が同じサーバー上にある必要があることを意味します。

W3Schoolsの例は、W3SchoolsドメインにあるすべてのオープンXMLファイルです。

上記の例を独自のWebページの1つで使用する場合、ロードするXMLファイルは独自のサーバーに配置する必要があります。

詳細については、ここで読み続けることができます ...


5

JavaScriptで新しい Fetch APIを使用できます。このような:

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

利点: Fetch APIはすべての最新のブラウザーでネイティブにサポートされているため、何もインポートする必要はありません。また、fetch()はPromiseを返すことに注意してください。このPromiseは、.then(..code to handle response..)非同期で使用して処理されます。


4

プラグインを使用せずに、JavaScriptまたはjQueryを使用して非同期複数ファイルのアップロードを実行できます。また、進行状況コントロールでファイルのアップロードの進行状況をリアルタイムで表示することもできます。私は2つの素晴らしいリンクに出くわしました-

  1. ASP.NET Webフォームベースの複数ファイルアップロード機能とプログレスバー
  2. jQueryで作成されたASP.NET MVCベースの複数ファイルのアップロード

サーバー側の言語はC#ですが、PHPのような他の言語で動作させるためにいくつかの変更を行うことができます。

ファイルアップロードASP.NET Core MVC:

ビューでHTMLのファイルアップロードコントロールを作成します。

<form method="post" asp-action="Add" enctype="multipart/form-data">
    <input type="file" multiple name="mediaUpload" />
    <button type="submit">Submit</button>
</form>

コントローラでアクションメソッドを作成します。

[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
    //looping through all the files
    foreach (IFormFile file in mediaUpload)
    {
        //saving the files
        string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path"); 
        using (var stream = new FileStream(path, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }
    }
}

hostingEnvironment変数はIHostingEnvironment型であり、依存関係の注入を使用してコントローラーに注入できます。

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}

リンクされたWebサイトが変更されたりオフラインになったりした場合に役に立たなくなる可能性があるため、回答の中にソリューションの本質を含めることができますか。
ディマコジェビン

4

PHPの場合、https://developer.hyvor.com/php/image-upload-ajax-php-mysqlを探します。

HTML

<html>
<head>
    <title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit="submitForm(event);">
    <input type="file" name="image" id="image-selecter" accept="image/*">
    <input type="submit" name="submit" value="Upload Image">
</form>
<div id="uploading-text" style="display:none;">Uploading...</div>
<img id="preview">
</body>
</html>

ジャバスクリプト

var previewImage = document.getElementById("preview"),  
    uploadingText = document.getElementById("uploading-text");

function submitForm(event) {
    // prevent default form submission
    event.preventDefault();
    uploadImage();
}

function uploadImage() {
    var imageSelecter = document.getElementById("image-selecter"),
        file = imageSelecter.files[0];
    if (!file) 
        return alert("Please select a file");
    // clear the previous image
    previewImage.removeAttribute("src");
    // show uploading text
    uploadingText.style.display = "block";
    // create form data and append the file
    var formData = new FormData();
    formData.append("image", file);
    // do the ajax part
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            var json = JSON.parse(this.responseText);
            if (!json || json.status !== true) 
                return uploadError(json.error);

            showImage(json.url);
        }
    }
    ajax.open("POST", "upload.php", true);
    ajax.send(formData); // send the form data
}

PHP

<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);


 try {
    if (empty($_FILES['image'])) {
        throw new Exception('Image file is missing');
    }
    $image = $_FILES['image'];
    // check INI error
    if ($image['error'] !== 0) {
        if ($image['error'] === 1) 
            throw new Exception('Max upload size exceeded');

        throw new Exception('Image uploading error: INI Error');
    }
    // check if the file exists
    if (!file_exists($image['tmp_name']))
        throw new Exception('Image file is missing in the server');
    $maxFileSize = 2 * 10e6; // in bytes
    if ($image['size'] > $maxFileSize)
        throw new Exception('Max size limit exceeded'); 
    // check if uploaded file is an image
    $imageData = getimagesize($image['tmp_name']);
    if (!$imageData) 
        throw new Exception('Invalid image');
    $mimeType = $imageData['mime'];
    // validate mime type
    $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($mimeType, $allowedMimeTypes)) 
        throw new Exception('Only JPEG, PNG and GIFs are allowed');

    // nice! it's a valid image
    // get file extension (ex: jpg, png) not (.jpg)
    $fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
    // create random name for your image
    $fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
    // Create the path starting from DOCUMENT ROOT of your website
    $path = '/examples/image-upload/images/' . $fileName;
    // file path in the computer - where to save it 
    $destination = $_SERVER['DOCUMENT_ROOT'] . $path;

    if (!move_uploaded_file($image['tmp_name'], $destination))
        throw new Exception('Error in moving the uploaded file');

    // create the url
    $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
    $domain = $protocol . $_SERVER['SERVER_NAME'];
    $url = $domain . $path;
    $stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
    if (
        $stmt &&
        $stmt -> bind_param('s', $url) &&
        $stmt -> execute()
    ) {
        exit(
            json_encode(
                array(
                    'status' => true,
                    'url' => $url
                )
            )
        );
    } else 
        throw new Exception('Error in saving into the database');

} catch (Exception $e) {
    exit(json_encode(
        array (
            'status' => false,
            'error' => $e -> getMessage()
        )
    ));
}

4

https://uppy.ioのようなものを使用することも検討できます

ページから移動せずにファイルをアップロードし、ドラッグアンドドロップ、ブラウザのクラッシュや不安定なネットワークの場合にアップロードを再開したり、Instagramなどからインポートしたりといったボーナスを提供します。これはオープンソースであり、jQuery / React / Angular / Vueに依存していませんが、一緒に使用できます。免責事項:私はその作成者として偏っています;)


上記のリンクは死んでいます。こちらがgithubです:github.com/transloadit/uppy
Chris Charles

uppy.ioはCloudFlare + GitHubページをサポートしていて、私のためにアップしていますか?ただし、ダイレクトリポジトリリンクを使用することもできます:)
kvz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.