Ringkasan masalah teknikal yang saya hadapi semasa membina pemalam muat naik fail HTML5
Mula-mula tampal kod sumber: fileupload-html5.js (PS: Syarikat menggunakan rangka kerja seajs)
Senarai Soalan
1. JQUERY.AJAX tidak memantau acara ONPROGRESS kemajuan muat naik.
2. XMLHTTPREQUEST (XHR) merentas domain
S&J
1. JQUERY tidak menyediakan antara muka untuk acara ONPROGRESS dan objek XHR asli mesti ditemui daripada antara muka lain.
jQuery.ajax() mengembalikan objek jqXHR. jqXHR meniru XHR (asli), tetapi tidak meniru semua kaedah dan atribut yang melaksanakan XHR (seperti: .upload), walaupun jika jqXHR menambah kaedah unik (seperti: .promise()). Jadi jqXHR bukanlah superset XHR.
//下面是截取jQ内部的源码,$.ajax();返回的就是这个jqXHR(伪造XMLHttpRequest) // Fake xhr jqXHR = { readyState: 0,
Atribut muat naik XHR menghala ke XMLHttpRequestUpload (IE10 ialah XMLHttpRequestEventTarget), dan acara onprogress objek ini boleh memantau kemajuan muat naik. Memandangkan jQ tidak menyediakan API untuk fungsi ini, beberapa kaedah muat naik data jQ menggunakan XHR, jadi kami boleh mencari XHR daripada API lain. Mengikat peristiwa dalam kemajuan sebelum XHR menghantar data boleh melaksanakan fungsi kemajuan muat naik.
Saya menemui dua sifat yang berkaitan dengan XHR daripada konfigurasi parameter OPTIONS:
- XHR: Panggilan balik mencipta objek XMLHTTPREQUEST.
Nilai pulangan xhr() ialah XHR, yang disediakan untuk kegunaan jQ, iaitu XHR ini digunakan untuk menghantar data. Kita boleh mencipta fungsi panggil balik melalui xhr untuk menulis gantinya, juga mengembalikan XHR, tetapi mengikat acara onprogress di sini.
//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 ); }
Jadi kita harus melakukan ini:
$.ajax({ //..... xhr: function() { var xhr = $.ajaxSettings.xhr(); //绑定上传进度的回调函数 xhr.upload.addEventListener('progress', progress, false); return xhr;//一定要返回,不然jQ没有XHR对象用了 } });
- XHRFIELDS: Pemetaan yang terdiri daripada sepasang "nilai fail nama fail", digunakan untuk menetapkan objek XHR asli.
Atribut xhrFields menunjuk kepada XHR yang dicipta secara dalaman oleh jQ, dan kami boleh mendapatkan XMLHttpRequest berdasarkan xhrFields. Oleh kerana nilai xhrFields hanya boleh menjadi objek json, ia tidak boleh diperoleh dengan cara berikut.
//错误例子 $.ajax({ //...... xhrFields: { upload.onprogress: function() { //语法错误 } } });
Kami boleh menggunakan acara onsendstart XHR, seperti berikut:
$.ajax({ //...... xhrFields: { onsendstart: function() { //this是指向XHR this.upload.addEventListener('progress', progress, false); } } });
2. XMLHTTPREQUESTⅡ(XHR) menyokong domain silang, tetapi memerlukan kebenaran latar belakang.
//后台需发送头部验证 if($_REQUEST['cros']) { header("Access-Control-Allow-Origin:请求的域名"); }
Mengikut antara muka yang disediakan oleh latar belakang, saya perlu menambah parameter cros. Tetapi apabila saya menyerahkan parameter ini dengan fail, ia telah digesa untuk sekatan merentas domain. Akhir sekali, letakkan parameter ini dalam url.
Ternyata XHR mempunyai dua permintaan merentas domain Yang pertama ialah permintaan pengesahan Penyemak imbas secara automatik mengeluarkan permintaan pilihan berdasarkan alamat destinasi permintaan. Jika lulus, permintaan pos tersuai boleh dikeluarkan. Jadi letakkan parameter dalam permintaan pos Permintaan pertama tidak mempunyai parameter cros, iaitu, ia tidak boleh lulus.