ホームページ >ウェブフロントエンド >jsチュートリアル >アップロード進行状況の実装時に jQuery+formdata で発生した問題
HTML5 ファイル アップロード プラグインを構築するときに遭遇した技術的問題の概要
まずソースコードを貼り付けます: fileupload-html5.js (追記: 会社は seajs フレームワークを使用しています)
質問リスト
1. JQUERY.AJAX はアップロードの進行状況を示す ONPROGRESS イベントを監視しません。
2. XMLHTTPREQUEST (XHR) クロスドメイン
Q&A
1. JQUERY は ONPROGRESS イベントのインターフェイスを提供しないため、ネイティブ XHR オブジェクトは他のインターフェイスから見つける必要があります。
jQuery.ajax() は jqXHR オブジェクトを返します。 jqXHR は XHR (ネイティブ) を模倣しますが、jqXHR が独自のメソッド (.promise() など) を追加する場合でも、XHR を実装するすべてのメソッドと属性 (.upload など) を模倣するわけではありません。したがって、jqXHR は XHR のスーパーセットではありません。
//下面是截取jQ内部的源码,$.ajax();返回的就是这个jqXHR(伪造XMLHttpRequest) // Fake xhr jqXHR = { readyState: 0,
XHR のアップロード属性は XMLHttpRequestUpload (IE10 は XMLHttpRequestEventTarget) を指しており、このオブジェクトの onprogress イベントでアップロードの進行状況を監視できます。 jQ はこの関数の API を提供していないため、jQ の一部のデータ アップロード メソッドは XHR を使用するため、他の API から XHR を見つけることができます。 XHR がデータを送信する前に onprogress イベントをバインドすると、アップロード進行状況関数を実装できます。
OPTIONS パラメータ設定から XHR に関連する 2 つのプロパティを見つけました:
- XHR: コールバックは XMLHTTPREQUEST オブジェクトを作成します。
xhr() の戻り値は XHR であり、これは jQ が使用するために提供されます。つまり、この XHR はデータの送信に使用されます。 xhr を介してコールバック関数を作成して上書きし、XHR を返すこともできますが、ここで onprogress イベントをバインドします。
//jQ源码 // Get a new xhr var handle, i, xhr = s.xhr();//[回调]在这里,下面是open方法 // Open the socket // Passing null username, generates a login popup on Opera (#2865) if ( s.username ) { xhr.open( s.type, s.url, s.async, s.username, s.password ); } else { xhr.open( s.type, s.url, s.async ); }
したがって、次のようにする必要があります:
$.ajax({ //..... xhr: function() { var xhr = $.ajaxSettings.xhr(); //绑定上传进度的回调函数 xhr.upload.addEventListener('progress', progress, false); return xhr;//一定要返回,不然jQ没有XHR对象用了 } });
- XHRFIELDS: ネイティブ XHR オブジェクトを設定するために使用される、「ファイル名とファイル値」のペアで構成されるマッピング。
xhrFields 属性は、jQ によって内部的に作成された XHR を指し、xhrFields に基づいて XMLHttpRequest を取得できます。 xhrFields の値は json オブジェクトしか取り得ないため、以下の方法では取得できません。
//错误例子 $.ajax({ //...... xhrFields: { upload.onprogress: function() { //语法错误 } } });
次のように XHR の onsendstart イベントを使用できます:
$.ajax({ //...... xhrFields: { onsendstart: function() { //this是指向XHR this.upload.addEventListener('progress', progress, false); } } });
2. XMLHTTPREQUESTⅡ(XHR)はクロスドメインをサポートしていますが、バックグラウンド権限が必要です。
//后台需发送头部验证 if($_REQUEST['cros']) { header("Access-Control-Allow-Origin:请求的域名"); }
バックグラウンドで提供されるインターフェイスによると、パラメータ cro を追加する必要があります。しかし、このパラメータをファイルとともに送信すると、クロスドメインの制限を求めるプロンプトが表示されました。最後に、このパラメータを URL に入力します。
XHR には 2 つのクロスドメイン リクエストがあることがわかりました。1 つ目は、リクエストの宛先アドレスに基づいてオプション リクエストを自動的に発行することです。合格すると、カスタム投稿リクエストを発行できます。したがって、post リクエストにパラメータを入力します。最初のリクエストには cro パラメータがありません。つまり、渡すことができません。