首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

SWFUpload + jQuery 實現 AJAX 無刷新圖片上傳完整範例

     編輯:ASP.NET 基礎

技術選型說明

傳統 `` 需整頁 PostBack,體驗差。SWFUpload 利用 Flash 繞過瀏覽器限制,提供:

  • 多檔案選擇、進度條、客戶端檔案型別/大小驗證
  • 背景上傳不刷新頁面,支援大檔案分塊
  • 豐富事件回呼(選擇、進度、成功、失敗、完成)
注意:Flash 已停止支援,現代專案建議改用 HTML5 File API + FormData + XMLHttpRequest/fetch 或成熟套件(Fine Uploader, Uppy, Dropzone.js)。本文保留為維護舊專案參考。

一、前端頁面:ChangeAvatar.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ChangeAvatar.aspx.cs" Inherits="NovelChannel.ChangeAvatar" %>
<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
    <title>大頭貼上傳</title>
    <link href="/CSS/jQueryUI/jquery-ui-1.10.2.custom.css" rel="stylesheet" />
    <script src="/JS/jQuery/jquery-1.9.1.js"></script>
    <script src="/JS/jQuery/jquery-ui-1.10.2.custom.js"></script>
    <script src="/JS/swf/swfupload.js"></script>
    <script src="/JS/swf/handlers.js"></script>
    <style>
        #avatarContainer { width:200px; height:300px; border:1px solid #ccc; background-size:cover; background-position:center; }
        #draggable { width:50px; height:50px; background:transparent; border:1px solid #000; cursor:move; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <span id="btnUploadImgPlaceholder"></span>
        <div id="divFileProgressContainer"></div>
        <br />
        <div id="avatarContainer">
            <div id="draggable">拖曳</div>
        </div>
        <img id="imgAvatar" style="display:none;" />
    </form>

    <script type="text/javascript">
        // 1. 上傳成功回呼:解析 JSON,更新預覽區
        function uploadImgSuccess(file, response) {
            var data = $.parseJSON(response); // [path, width, height]
            $("#avatarContainer").css({
                "background-image": "url(" + data[0] + ")",
                "width": data[1] + "px",
                "height": data[2] + "px"
            });
        }

        $(function () {
            // 2. 初始化 SWFUpload
            var swfu = new SWFUpload({
                // 後端設定
                upload_url: "/Ajax/UploadAvatar.ashx",
                post_params: { "ASPSESSID": "<%=Session.SessionID %>" }, // 傳遞 Session ID 維持登入狀態

                // 檔案限制
                file_size_limit: "2 MB",
                file_types: "*.jpg",
                file_types_description: "JPG Images",
                file_upload_limit: 0,

                // 事件處理器(定義於 handlers.js)
                swfupload_preload_handler: preLoad,
                swfupload_load_failed_handler: loadFailed,
                file_queue_error_handler: fileQueueError,
                file_dialog_complete_handler: fileDialogComplete,
                upload_progress_handler: uploadProgress,
                upload_error_handler: uploadError,
                upload_success_handler: uploadImgSuccess,
                upload_complete_handler: uploadComplete,

                // 按鈕外觀
                button_image_url: "/JS/swf/images/XPButtonNoText_160x22.png",
                button_placeholder_id: "btnUploadImgPlaceholder",
                button_width: 160,
                button_height: 22,
                button_text: '<span class="button">選擇圖片(最大2MB)</span>',
                button_text_style: '.button { font-family: Helvetica, Arial, sans-serif; font-size: 14pt; }',
                button_text_top_padding: 1,
                button_text_left_padding: 5,

                // Flash 檔案路徑
                flash_url: "/JS/swf/swfupload.swf",
                flash9_url: "/JS/swf/swfupload_FP9.swf",

                custom_settings: { upload_target: "divFileProgressContainer" },
                debug: false
            });
        });

        // 3. jQuery UI 拖曳(示範用,非上傳核心)
        $(function () {
            $("#draggable").draggable({ containment: "parent", cursor: "crosshair" });
            $("#draggable").dblclick(function () {
                var pos = $(this).position();
                alert("相對座標: " + pos.left + ", " + pos.top);
            });
        });
    </script>
</body>
</html>

二、後端處理程序:UploadAvatar.ashx

using System;
using System.IO;
using System.Drawing;
using System.Web;
using System.Web.Script.Serialization;

namespace NovelChannel.Ajax
{
    public class UploadAvatar : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";

            HttpPostedFile file = context.Request.Files["FileData"]; // SWFUpload 固定欄位名
            if (file == null || file.ContentLength == 0)
            {
                context.Response.Write("未收到檔案");
                return;
            }

            // 1. 驗證副檔名
            string ext = Path.GetExtension(file.FileName).ToLower();
            if (ext != ".jpg" && ext != ".jpeg")
            {
                context.Response.Write("只允許 JPG 格式");
                return;
            }

            // 2. 產生唯一檔名
            string fileName = DateTime.Now.ToString("yyMMddHHmmss") + new Random().Next(1000, 9999) + ".jpg";
            string relPath = "/Images/UserImg/" + fileName;
            string fullPath = context.Server.MapPath("~" + relPath);

            // 3. 確保目錄存在
            Directory.CreateDirectory(Path.GetDirectoryName(fullPath));

            // 4. 儲存原檔
            file.SaveAs(fullPath);

            // 5. 讀取圖片尺寸回傳 JSON
            using (Image img = Image.FromFile(fullPath))
            {
                var result = new string[] { relPath, img.Width.ToString(), img.Height.ToString() };
                var json = new JavaScriptSerializer().Serialize(result);
                context.Response.Write(json);
            }
        }

        public bool IsReusable => false;
    }
}

三、handlers.js 關鍵事件處理器(節錄)


// 檔案加入佇列後自動開始上傳
function fileDialogComplete(numFilesSelected, numFilesQueued) {
    if (numFilesQueued > 0) this.startUpload();
}

// 上傳進度條更新
function uploadProgress(file, bytesLoaded, bytesTotal) {
    var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
    $("#divFileProgressContainer").html("上傳中: " + percent + "%");
}

// 上傳失敗處理
function uploadError(file, errorCode, message) {
    alert("上傳失敗: " + message);
    $("#divFileProgressContainer").html("失敗");
}

// 上傳完成(無論成敗)清理佇列
function uploadComplete(file) {
    if (this.getStats().files_queued > 0) this.startUpload();
}

關鍵整合細節

項目說明
Session 傳遞SWFUpload 另開請求不自動帶 Cookie,需手動傳 ASPSESSID,後端 context.Request.Cookies["ASP.NET_SessionId"] 讀取
檔案欄位名SWFUpload 固定上傳欄位為 FileData,後端 Request.Files["FileData"] 取得
跨域/信任Flash 需 crossdomain.xml 或同網域部署
錯誤代碼參考 SWFUpload 文檔:SWFUpload.QUEUE_ERROR.*, SWFUpload.UPLOAD_ERROR.*

現代化替代方案(建議新專案採用)

// HTML5 + FormData + fetch 範例
const input = document.querySelector('#fileInput');
input.addEventListener('change', async (e) => {
    const file = e.target.files[0];
    const formData = new FormData();
    formData.append('file', file);
    const res = await fetch('/api/upload', { method: 'POST', body: formData });
    const data = await res.json();
    // 更新預覽...
});

優點:無外掛相依、原生支援進度、行動裝置相容、安全性高。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved