


Bercakap tentang tiga kaedah memuat naik fail tanpa menyegarkan semula berdasarkan kemahiran iframe, FormData dan FileReader_javascript
Terdapat dua cara untuk menghantar permintaan, satu adalah menggunakan ajax, satu lagi adalah menggunakan penyerahan borang Jika penyerahan borang lalai tidak diproses, halaman akan diubah hala. Mari gunakan demo ringkas untuk menggambarkan:
html adalah seperti yang ditunjukkan di bawah, tindakan laluan yang diminta ialah "muat naik", dan tiada pemprosesan lain akan dilakukan:
<form method="POST" action="upload" enctype="multipart/form-data"> 名字 <input type="text" name="user"></input> 头像 <input type="file" name="file"></input> <input type="submit" id="_submit" value="提交"></input> </form>
Respons pelayan (nod) kembali secara langsung: "Data borang yang diterima", demonstrasi adalah seperti berikut:
Anda boleh melihat bahawa secara lalai, borang meminta muat naik dan mengubah hala untuk dimuat naik pada masa yang sama. Tetapi dalam banyak kes, kami berharap permintaan borang akan menjadi seperti ajax dan tidak akan mengubah hala atau memuat semula halaman. Seperti senario di atas, selepas muat naik selesai, avatar yang dipilih oleh pengguna dipaparkan pada halaman semasa.
Penyelesaian pertama ialah menggunakan FormData html5, merangkum data dalam borang ke dalam objek FormData, dan kemudian menghantarnya keluar melalui POST. Seperti yang ditunjukkan dalam kod berikut, balas peristiwa klik butang hantar Baris 6 kod memperoleh objek DOM borang, kemudian bina contoh FormData pada baris 8 dan menghantar data borang pada baris 18.
document.getElementById("_submit").onclick = function(event){ //取消掉默认的form提交方式 if(event.preventDefault) event.preventDefault(); else event.returnValue = false; //对于IE的取消方式 var formDOM = document.getElementsByTagName("form")[]; //将form的DOM对象当作FormData的构造函数 var formData = new FormData(formDOM); var req = new XMLHttpRequest(); req.open("POST", "upload"); //请求完成 req.onload = function(){ if(this.status === ){ //对请求成功的处理 } } //将form数据发送出去 req.send(formData); //避免内存泄漏 req = null; }
Selepas muat naik berjaya, perkhidmatan akan mengembalikan alamat akses imej, dan menambah 14 baris untuk mengendalikan permintaan yang berjaya: paparkan imej yang dimuat naik di atas butang hantar:
var img = document.createElement("img"); img.src = JSON.parse(this.responseText).path; formDOM.insertBefore(img, document.getElementById("_submit"));
Contoh:
Jika anda menggunakan jQuery, anda boleh menggunakan formData sebagai parameter data ajax, dan tetapkan contentType: false dan processData: false pada masa yang sama untuk memberitahu jQuery supaya tidak memproses pengepala permintaan dan data yang dihantar.
Nampaknya kaedah penyerahan ini adalah sama dengan ajax, tetapi ia tidak betul-betul sama. Terdapat tiga format data untuk penyerahan borang Jika anda ingin memuat naik fail, ia mestilah multipart/form-data http dalam permintaan penyerahan borang di atas Jenis Kandungan dalam maklumat pengepala adalah multipart/form-data, manakala penyerahan ajax biasa ialah application/json. Jenis Kandungan lengkap yang diserahkan oleh borang adalah seperti berikut:
"content-type":"multipart/form-data; boundary=------WebKitFormBoundaryYOE7pWLqdFYSeBFj"
Selain data berbilang bahagian/bentuk, sempadan juga ditetapkan Tujuan sempadan ini adalah untuk membezakan medan yang berbeza. Memandangkan objek FormData adalah legap, memanggil JSON.stringify akan mengembalikan objek kosong {}. Pada masa yang sama, FormData hanya menyediakan kaedah tambah, jadi kandungan sebenar FormData yang dimuat naik tidak boleh diperoleh, tetapi ia boleh dilihat melalui data diterima oleh alat atau perkhidmatan analisis. Jika anda memuat naik fail teks di atas, format asal data POST yang diterima oleh perkhidmatan adalah seperti berikut:
------WebKitFormBoundaryYOE7pWLqdFYSeBFj
Pelupusan Kandungan: form-data; name="user"
abc
------WebKitFormBoundaryYOE7pWLqdFYSeBFj
Pelupusan Kandungan: form-data; name="file"; filename="test.txt"
Jenis Kandungan: teks/biasa
Ini ialah kandungan fail teks.
------WebKitFormBoundaryYOE7pWLqdFYSeBFj--
Daripada data yang diterima oleh perkhidmatan di atas, kita dapat melihat format yang dihantar oleh FormData Setiap medan dipisahkan oleh sempadan dan berakhir dengan --. Untuk permintaan ajax, format data yang dihantar disesuaikan, biasanya dengan key=value dan & di tengah:
var req = new XMLHttpRequest(); var sendData = "user=abc&file=这是一个文本文件的内内容"; req.open("POST", "upload"); //发送的数据需要转义,见上面提到的三种格式 req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); req.send(sendData);
服务就会收到和send发出去的字符串一模一样的内容,然后再作参数解析,所以就得统一参数的格式:
user=abc&file=这是一个文本文件的内容
从这里可以看出POST本质上并不比GET安全,POST只是没有将数据放在网址传送而已。
考虑到FormData到了IE10才支持,如果要支持较低版本的IE,那么可以借助iframe。
文中一开始就说,默认的form提交会使页面重定向,而重定向的规则在target中指定,可以和a标签一样指定为"_blank",在新窗口中打开;还可以指定为一个iframe,在该iframe中打开。所以可以弄一个隐藏的iframe,将form的target指向这个iframe,当form请求完成时,返回的数据就会由这个iframe显示,正如上面在新页面显示的:"Recieved form data"。请求完成后,iframe加载完成,触发load事件,在load事件的处理函数里,获取该iframe的内容,从而拿到服务返回的数据了!拿到后再把iframe删掉。
在提交按钮的响应函数里,首先创建一个iframe,设置iframe为不可见,然后再添加到文档里:
var iframe = document.createElement("iframe"); iframe.width = 0; iframe.height = 0; iframe.border = 0; iframe.name = "form-iframe"; iframe.id = "form-iframe"; iframe.setAttribute("style", "width:0;height:0;border:none"); //放到document this.form.appendChild(iframe);
改变form的target为iframe的name值:
this.form.target = "form-iframe";
然后再响应iframe的load事件:
iframe.onload = function(){ var img = document.createElement("img"); //获取iframe的内容,即服务返回的数据 var responseData = this.contentDocument.body.textContent || this.contentWindow.document.body.textContent; img.src = JSON.parse(responseData).path; f.insertBefore(img, document.getElementById("_submit")); //删掉iframe setTimeout(function(){ var _frame = document.getElementById("form-iframe"); _frame.parentNode.removeChild(_frame); }, 100); //如果提示submit函数不存在,请注意form里面是否有id/value为submit的控件 this.form.submit(); }
第二种办法到这里就基本可以了,但是如果看163邮箱或者QQ邮箱上传文件的方式,会发现和上面的两种方法都不太一样。用httpfox抓取请求的数据,会发现上传的内容的格式并不是上面说的用boundary隔开,而是直接把文件的内容POST出去了,而文件名、文件大小等相关信息放在了文件的头部。如163邮箱:
POST Data:
this is a text
Headers:
Mail-Upload-name: content.txt
Mail-Upload-size: 15
可以推测它们应该是直接读取了input文件的内容,然后直接POST出去了。要实现这样的功能,可以借助FileReader,读取input文件的内容,再保留二进制的格式发送出去:
var req = new XMLHttpRequest(); req.open("POST", "upload"); //设置和邮箱一样的Content-Type req.setRequestHeader("Content-Type", "application/octet-stream"); var fr = new FileReader(); fr.onload = function(){ req.sendAsBinary(this.result); } req.onload = function(){ //一样,省略 } //读取input文件内容,放到fileReader的result字段里 fr.readAsBinaryString(this.form["file"].files[0]);
代码第13行执行读文件,读取完毕后触发第6行的load响应函数,第7行以二进制文本形式发送出去。由于sendAsBinary的支持性不是很好,可以自行实现一个:
if(typeof XMLHttpRequest.prototype.sendAsBinary === 'undefined'){ XMLHttpRequest.prototype.sendAsBinary = function(text){ var data = new ArrayBuffer(text.length); var uia = new UintArray(data, ); for (var i = ; i < text.length; i++){ uia[i] = (text.charCodeAt(i) & xff); } this.send(uia); } }
代码的关键在于第6行,将字符串转成8位无符号整型,还原二进制文件的内容。在执行了fr.readAsBinaryString之后,二进制文件的内容将会以utf-8的编码以字符串形式存放到result,上面的第6行代码将每个unicode编码转成整型(&0xff或者parseInt),存放到一个8位无符号整型数组里面,第8行把这个数组发送出去。如果直接send,而不是sendAsBinary,服务收到的数据将无法正常还原成原本的文件。
上面的实现需要考虑文件太大,需分段上传的问题。
关于FileReader的支持性,IE10以上支持,IE9有另外一套File API。
文章讨论了3种办法实现无刷新上传文件,分别是使用iframe、FormData和FileReader,支持性最好是的iframe,但是从体验的效果来看FormData和FileReader更好,因为这两者不用生成一个无用的DOM再删除,其中FormData最简单,而FileReader更加灵活。
下面给大家介绍iframe无刷新上传文件
form.html <form enctype="multipart/form-data" method="post" target="upload" action="upload.php" > <input type="file" name="uploadfile" /> <input type="submit" /> </form> <iframe name="upload" style="display:none"></iframe>

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Bingkai sebaris dipanggil iframe dalam HTML. Label menentukan kawasan segi empat tepat dalam kandungan di mana penyemak imbas boleh memaparkan dokumen yang berbeza dengan bar skrol dan sempadan. Untuk membenamkan dokumen lain dalam dokumen HTML semasa, gunakan bingkai sebaris. Rujukan kepada elemen boleh ditentukan menggunakan atribut nama HTMLiframe. Dalam JavaScript, rujukan kepada elemen juga dibuat menggunakan atribut nama. Iframe pada asasnya digunakan untuk memaparkan halaman web dalam halaman web yang sedang dipaparkan. URL dokumen yang mengandungi iframe ditentukan menggunakan atribut "src". Sintaks Berikut ialah sintaks HTML <iframesrc="URL"title="d

Sebab untuk memuatkan iframe yang perlahan terutamanya termasuk kelewatan rangkaian, masa pemuatan sumber yang lama, susunan pemuatan, mekanisme caching dan dasar keselamatan. Pengenalan terperinci: 1. Kelewatan rangkaian Apabila pelayar memuatkan halaman web yang mengandungi iframe, ia perlu menghantar permintaan kepada pelayan untuk mendapatkan kandungan dalam iframe Jika kelewatan rangkaian adalah tinggi, masa untuk mendapatkan kandungan akan meningkat, mengakibatkan pemuatan iframe yang perlahan ; dll.

Data-id dalam iframe merujuk kepada atribut tersuai yang digunakan dalam teg HTML untuk menyimpan pengecam elemen tertentu. Dengan menggunakan atribut data-id, anda boleh menambah pengecam unik pada elemen iframe supaya ia boleh dimanipulasi dan diakses dalam JavaScript. Penamaan atribut data-id boleh disesuaikan mengikut keperluan khusus, tetapi beberapa konvensyen penamaan biasanya diikuti untuk memastikan keunikan dan kebolehbacaannya. Atribut data-id juga boleh digunakan untuk mengenal pasti dan memanipulasi iframe tertentu.

Microsoft Outlook sedang memuat turun fail misteri yang dipanggil "TokenFactoryIframe" pada macOS apabila pengguna mengakses perkhidmatan e-mel melalui pelayar Safari. Isu ini kini telah dilaporkan secara meluas oleh pengguna yang telah menemui fail "TokenFactoryIframe" yang dimuat turun oleh Outlook pada setiap lawatan. Outlook memuat turun fail misteri ini setiap beberapa saat atau sekurang-kurangnya setiap kali anda mengakses Outlook pada platform Apple. Berdasarkan penemuan kami, ini nampaknya merupakan isu yang disebabkan oleh kemas kini sebelah pelayan yang tidak betul yang disiarkan ke Outlook dan tiada kaitan dengan Safari atau macOS. Microsoft dalam satu salinan

Teknologi yang boleh menggantikan iframe termasuk Ajax, perpustakaan atau rangka kerja JavaScript, teknologi komponen Web, penghalaan bahagian hadapan dan pemaparan sebelah pelayan. Pengenalan terperinci: 1. Ajax ialah teknologi yang digunakan untuk mencipta laman web dinamik. Ia boleh mencapai kemas kini tak segerak halaman dengan menukar data dengan pelayan di latar belakang tanpa menyegarkan keseluruhan halaman Menggunakan Ajax boleh memuatkan dan memaparkan kandungan dengan lebih fleksibel, dan tidak perlu menggunakan iframe untuk membenamkan halaman lain atau rangka kerja , seperti React dan sebagainya.

Peristiwa pemuatan iframe termasuk acara onload, acara onreadystatechange, acara onbeforeunload, acara onerror, acara onabort, dsb. Penerangan terperinci: 1. acara onload, menentukan kod JavaScript untuk dilaksanakan selepas memuatkan acara iframe 2. onreadystatechange, menentukan kod JavaScript untuk dilaksanakan apabila keadaan iframe berubah, dsb.

iframe dalam Python ialah teg HTML yang digunakan untuk membenamkan halaman web atau dokumen lain dalam halaman web. Dalam Python, anda boleh menggunakan pelbagai perpustakaan dan rangka kerja untuk memproses dan memanipulasi iframe, yang paling biasa digunakan ialah perpustakaan BeautifulSoup, yang boleh mengekstrak kandungan iframe dengan mudah daripada halaman web dan memanipulasi serta memprosesnya. Mengetahui cara mengendalikan dan memanipulasi iframe sangat berguna untuk pembangunan web dan mengikis data.

Bahaya dalam iframe terutamanya termasuk: 1. Kerentanan keselamatan halaman web berniat jahat boleh memuatkan halaman web lain melalui iframe dan melakukan beberapa serangan 2. Penembusan dasar yang sama Dengan memuatkan halaman web di bawah nama domain lain, yang sama-. Dasar asal boleh dilanggar Strategi untuk mencapai komunikasi merentas domain, yang mungkin diserang secara berniat jahat 3. Isu pelaksanaan kod, halaman web yang dimuatkan dalam iframes boleh melaksanakan kod JS, yang mungkin menyebabkan beberapa isu keselamatan; mungkin tidak dapat menghuraikan dengan betul dan kandungan Indeks dimuatkan melalui iframe dan banyak lagi.
