ajax 模式得上傳

來源:互聯網
上載者:User
如題所示,實現一個Ajax模式的檔案上傳有多難?這並不是一個疑問句,這是一個反問句。

  在這裡我先聲明,不要認為一提到Ajax就是講XHttpRequest, Ajax還要包括基於frame的操作,對!我說的是古老的frame。

  xhttpRequest並不能實現檔案上傳,所以涉及到檔案的上傳,我們還得回到frame上,尤其是iframe。

  需要的材料:

  1,你掌握基本的Javascript技能。
  2,一個隱藏的form和iframe,這裡我分別命名為uploadForm和uploadResponse.
  3,一個負責接收檔案的頁面,名字叫做UploadImage.aspx。
  4,一個負責顯示檔案的頁面,名字叫做File.aspx。

  基本原理:

  通過複製當前form(form1)中的input type=file 的html元素到另一個專用於檔案上傳的form(uploadForm)中,而切uploadForm的target指向到一個隱藏的iframe(uploadResponse)架構的name.這樣,當執行uploadForm的submit()操作時,就會通過uploadResponse將uploadForm的內容post到UploadImage.aspx頁面去執行,由於iframe元素uploadResponse及form元素uploadForm元素都是位於一個隱藏的div元素中,所以訪問者自始至終都不會見到多餘的東西。

  執行個體:

Default.aspx頁面。

<script type="text/javascript">

function uploadImage() {
var file = document.getElementById("imageFile");
var uploadFormElement = document.getElementById("uploadForm");

//顯示進度條
document.getElementById("processDiv").style.display = "block"; // the progress div

//複製圖片資料
uploadFormElement.removeChild(uploadFormElement.imageFile);
uploadFormElement.appendChild(file);
document.getElementById("uploadImageDiv").innerHTML = '<input type="file" id="imageFile" name="imageFile" />';

//提交圖片資料
uploadFormElement.submit();
}

function uploadImageResponse(response) {
document.getElementById("processDiv").style.display = "none"; // hide progresss div
var errLabel = document.getElementById("uploadMessage");
errLabel.innerHTML = "";
window.eval("var k=" + response);
if (k.status == 1)
errLabel.innerHTML = k.message;
else if (k.status == 2)
errLabel.innerHTML = k.message;
else
eval("tinyMCE.activeEditor.dom.add(tinyMCE.activeEditor.getBody(), 'img', { src:'" + k.message + "',style:'border:0px; '}, null); ");

}

function uploadButton_onclick() {

}

</script>

<form id="form1" runat="server">
<div>
<!-- Gets replaced with TinyMCE, remember HTML in a textarea should be encoded -->
<tinymce:TextArea ID="elm1" theme="advanced" plugins="spellchecker,safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template"
theme_advanced_buttons1="bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,fontselect,fontsizeselect,forecolor,backcolor,image"
theme_advanced_buttons2="" theme_advanced_buttons3="" theme_advanced_buttons4=""
theme_advanced_toolbar_location="top" theme_advanced_toolbar_align="left" theme_advanced_path_location="bottom"
theme_advanced_resizing="true" runat="server" />
<div style="margin-top: 5px">
上傳圖片:
<br />
<div id="uploadImageDiv">
<input type="file" id="imageFile" name="imageFile" /></div>
<input type="button" id="uploadButton" onclick="uploadImage(); " value="上傳" />
<span id="uploadMessage" style="border: 1px solid #cccccc; color: Red; "></span>
</div>
<div id="processDiv" style="display: none; color: #660066; font-family: Arial; ">
<img src="http://images.cnblogs.com/loading2.gif" alt="uploading" />
圖片上傳中 <span id="fileName" />
</div>
</div>
</form>
<div style="display: none; ">
<iframe name="uploadResponse"></iframe>
<form id="uploadForm" action="UploadImage.aspx?t=<%= DateTime.Now.Ticks %>" target="uploadResponse"
method="post" enctype="multipart/form-data">
<input type="file" name="imageFile" value="" />
</form>
</div>

  如上所示,首先選擇準備上傳的檔案,然後當你點擊上傳按鈕(name為uploadButton)時,調用uploadImage函數,該函數的作用是複製form1的input type=file的imageFile元素到uploadForm中,並替換原始的imageFile的outerhtml(原因是javascript不支援修改input type=file的元素的value屬性),當然還有顯示可愛的上傳進度條(這樣顯得我們既專業又酷)。

function uploadImage() {
var file = document.getElementById("imageFile");
var uploadFormElement = document.getElementById("uploadForm");

//顯示進度條
document.getElementById("processDiv").style.display = "block"; // the progress div

//複製圖片資料
uploadFormElement.removeChild(uploadFormElement.imageFile);
uploadFormElement.appendChild(file);
document.getElementById("uploadImageDiv").innerHTML = '<input type="file" id="imageFile" name="imageFile" />';

//提交圖片資料
uploadFormElement.submit();
}

  當使用者點擊上傳按鈕時,工作轉由UploadImage.aspx程式接手。

protected void Page_Load(object sender, EventArgs e)
{
Page.Response.Cache.SetCacheability(HttpCacheability.NoCache);

int status = 0; //狀態
string message = ""; //反饋資訊

//檢查檔案
if (Request.Files.Count == 0)
{
status = 1;
message = "請先選擇要上傳的檔案";
RenderUploadScript(status, message);
}
string ext = Path.GetExtension(Request.Files[0].FileName).ToLower();
if (ext != ".jpg" && ext != ".jpeg")
{
status = 2;
message = "抱歉,目前僅支援jpg格式的圖片";
RenderUploadScript(status, message);
}

Guid fileID = Guid.NewGuid();
string fileName = Server.MapPath(String.Format("~\Files\{0}.jpg",fileID));
Request.Files[0].SaveAs(fileName);
//記錄到當前頁面

RenderUploadScript(0,String.Format( "File.aspx?key={0}",fileID));
}

private void RenderUploadScript(int status, string mess)
{
string script = string.Format("<script language='javascript'> window.parent.uploadImageResponse("{{ status:{0},message:'{1}'}}"); </script>", status, mess);
Response.Write(script);
Response.End();
}

  通過HttpWebRequest對象,我們能夠獲得任何由用戶端post或get到伺服器端的資料,UploadImage.aspx頁面的工作很簡單,只負責接收post過來的檔案,並儲存到指定的位置(方便示範,我僅僅使用了SaveAs)。

  另外,要注意到一點,由於是Ajax模式的檔案上傳,意味著你的程式要通過javascript反饋系統出現的問題,這裡我通過一個名稱為status的參數來返回出現的問題,0則為一切正常,1則為使用者沒有提供檔案,2則為使用者沒有上傳我指定的檔案類型。

  當使用者上傳的檔案沒有任何問題的時候,系統儲存檔案並返回狀態0,並附加檔案的顯示路徑,其他狀態附屬的資訊則是錯誤資訊。

  現在回到Default.aspx來看如何接收UploadImage.aspx反饋回來的資訊,這裡要考慮到UploadImage.aspx是個頁面,而且隸屬與iframe元素uploadResponse,所以我們通過javascipt來訪問uploadResponse的所屬window的對象或函數的寫法如下:

"<script language='javascript'> window.parent.uploadImageResponse("{{ status:0,message:'File.aspx?key=guid'}}"); <script>"

  Default的接應指令碼則如下:

function uploadImageResponse(response) {
document.getElementById("processDiv").style.display = "none"; // hide progresss div
var errLabel = document.getElementById("uploadMessage");
errLabel.innerHTML = "";
window.eval("var k=" + response);
if (k.status == 1)
errLabel.innerHTML = k.message;
else if (k.status == 2)
errLabel.innerHTML = k.message;
else
eval("tinyMCE.activeEditor.dom.add(tinyMCE.activeEditor.getBody(), 'img', { src:'" + k.message + "',style:'border:0px; '}, null); ");

}

  僅僅是在對應的htm編輯器的內容中插入message附帶的資訊。

  ok!!主要的痛點我們都解決了。下面則是要讓我們能夠看到我們傳上去的檔案,如果不能即時看到,這個Ajax 檔案上傳就沒啥意義了。

  File.aspx頁面的功能代碼如下:

protected void Page_Load(object sender, EventArgs e)
{

Guid key = new Guid(Request.QueryString["key"]);

//圖片所在路徑
string fileName = Server.MapPath(String.Format("~/Files/{0}.jpg", key));
// Send the file
Response.ContentType = "image/jpeg";
Response.WriteFile(fileName, true);
Response.AddFileDependency(fileName);
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetAllowResponseInBrowserHistory(true);
}

OK!一切都完成了。

示範程式:

http://files.cnblogs.com/csharpsharper/CoolThingsShow.rar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.