asp.net 無重新整理檔案上傳(利用iframe)源碼(1/4)

來源:互聯網
上載者:User

先來看效果圖。

我們先來下載外掛程式完全執行個體源碼

asp版 http://down.111cn.net/down/code/asp/2012/0508/24173.html

asp.net版 http://down.111cn.net/down/code/asp/2012/0508/24172.html

【upload】

程式中最重要的方法就是upload了,調用它就可以進行無重新整理上傳。
upload的過程是這樣的,首先用stop方法停止上一次上傳,並判斷是否選擇檔案。
然後分別調用_setIframe,_setForm和_setInput,產生需要的iframe,form和input。

如果設定了timeout屬性的話,會自動化佈建計時器:

 代碼如下 複製代碼

if ( this.timeout > 0 ) {
this._timer = setTimeout( $$F.bind(this._timeout, this), this.timeout * 1000 );
}

ps:經測試,小於0的延時時間,ie會取消執行,而其他瀏覽器會當成0執行。

程式有一個_sending屬性用來判斷上傳狀態。
在stop(停止),dispose(銷毀),_finis(完成),_timeout(逾時)時會把它設為false。
而在上傳開始前要把它設定為true。

最後提交表單就開始上傳了。

【iframe】

程式使用_setIframe函數來建立無重新整理需要的iframe。

由於ie中iframe的name不能修改的問題,要這樣建立iframe:

 代碼如下 複製代碼

var iframename = "QUICKUPLOAD_" + QuickUpload._counter++,
iframe = document.createElement( $$B.ie ? "<iframe name="" + iframename + "">" : "iframe");
iframe.name = iframename;
iframe.style.display = "none";

ps:關於iframe的name的問題參考這裡的iframe部分。
ie8已經可以修改name了,但在非標準(怪辟)模式下還是不能修改。
其中使用了一個QuickUpload函數自身的_counter屬性做計算機,這就能保證各個執行個體的iframe的name就不會重複。

為了能在檔案上傳完成後執行回呼函數,會在iframe的onload中執行_finish函數:

 代碼如下 複製代碼

var finish = this._fFINISH = $$F.bind(this._finish, this);
if ( $$B.ie ) {
iframe.attachEvent( "onload", finish );
} else {
iframe.onload = $$B.opera ? function(){ this.onload = finish; } : finish;
}

在ie需要用attachEvent來綁定onload,因為在ie中直接設定onload是無效的。
除了用attachEvent還可以用onreadystatechange代替。
至於原因我也不清楚,詳細參考“判斷 iframe 是否載入完成的完美方法”。

iframe的載入還有一個問題,測試以下代碼:

 

 代碼如下 複製代碼
<body><div id="msg">狀態:</div></body>
<script>
var msg = document.getElementById("msg");
var iframe = document.createElement("iframe");
iframe.onload = function(){ msg.innerHTML += "onload,"; }
document.body.appendChild(iframe);
iframe.src = "http://www.111cn.net/phper/php.html"
</script>

結果safari, chrome都會觸發onload兩次,而opera, ff和ie(請自行相容)都是1次。

估計在safari和chrome在appendChild之後就進行第一次載入,並且在設定src之前載入完畢,所以觸發了兩次。
如果在插入body之前給iframe隨便設定一個src(除了空值),間接加長第一次載入,那麼也只觸發一次了。
ps:不設定或空值的src相當於連結到“about:blank”(空白頁)。

那麼opera, ff和ie可能是第一次載入太慢,第二次覆蓋了第一次的,所以只觸發了一次onload。
ps:也可能是其他原因,例如瀏覽器最佳化之類的,我也不確定。

針對載入過快的問題,可以在onload的時候根據_sending確定之前是否上傳狀態來解決。
雖然沒測試出來,會不會有_sending設定之後submit之前剛好觸發第一次onload的情況呢?
針對這個問題,在upload方法中會把_sending放在submit之後設定。
那如果在submit之後_sending設定之前就觸發了onload呢?(...?澹
這個情況基本不會出現,如果真的出現,就把_sending設定放到submit前面吧。

opera還有一個麻煩的問題,測試下面代碼:

 代碼如下 複製代碼

<body>
<div id="msg">狀態:</div>
<form action="http://www.111cn.net" target="ifr">
</form>
</body>
<script>
var msg = document.getElementById("msg");
var iframe = document.createElement("iframe");
iframe.name = "ifr";
iframe.onload = function(){ msg.innerHTML += "onload,"; }
document.body.appendChild(iframe);
msg.innerHTML += "submit,";
document.forms[0].submit();
</script>

ie和ff顯示submit,onload,safari和chrome顯示的是onload,submit,onload,跟上面的分析一致。
而opera卻顯示submit,onload,onload,兩次onload都是在submit之後觸發的。
這個情況就不能單純用_sending來解決了。
是不是submit不能使iframe取消載入呢?
在appendChild之前設一個src,結果正常的只觸發onload一次,看來是可以的啊。

雖然不知道原因,辦法還是有的,一個是appendChild前設一個src,還可以在第一次onload中重新設定onload,像程式那樣。
但這兩個方法都存在不確定性,不能完全解決問題,但也找不到更好的方法了。

ff的onload還有一個問題,在出現ERROR_INTERNET_CONNECTION_RESET(檔案大小超過伺服器限制)之類的伺服器錯誤時,即使載入完成也不會觸發onload,暫時找不到解決辦法。

iframe有一個缺陷是只能用onload判斷載入完成,但沒有辦法判斷是否載入成功。
沒有類似XMLHTTP的status的東西,遇上404之類的錯誤也沒辦法判別出來。
在使用時要做好這方面的處理,例如說明允許上傳檔案大小,逾時時間,如何處理長時間無響應等。


首頁 1 2 3 4 末頁

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.