使用SWFUpload组件无刷新上传图片

使用SWFUpload组件无刷新上传图片

在做项目时,需要用到一个图片的无刷新上传,之前听说过SWFUpload,于是想要通过SWFUpload来进行图片的无刷新上传,由于我的项目属于是ASP.NET项目,所以本文着重讲解ASP.NET 的使用,个人感觉示例基本给的很清晰,参考文档进行开发,并非难事

0.     首先下载swfUpload 包,在下载的包中有samples文件夹,samples下有demos文件夹,打开demos文件夹可看到如下图所示结构

我们待会会用到的包括,swfupload目录下的文件,css不建议使用以避免与自己写的CSS相冲突使得页面布局完全乱掉,如果要添加样式最好自己写

打开 applicationdemo.net目录会看到这样的结构

打开index.html可以看到这样的页面

点击NET2.0下的Application Demo C#项

  1. 添加资源引用

将要引用的资源包含到项目中(包括swfupload文件夹下的文件与,demo下的资源文件,handlers.js是在demo中js目录下的js文件)

  1. 首先熟悉demo,将demo中的页面包含到项目中

    在Defaut.aspx页面中使用swfUpload组件进行图片的无刷新上传直接运行,看效果,大概了解基本过程

  2. 修改handlers.js文件

    我的项目文件结构大概是这样的

    我的处理文件上传的页面是ImageUploadHandler.ashx,获取缩略图的页面是GetThumbHandler.ashx,Thumbnail.cs是基于demo中的文件稍作了改动,个人觉得像这种只处理逻辑功能而不展现页面的最好都用一般处理程序来实现。由于哪个文件处理上传哪个文件生成缩略图已经在handlers.js文件中写死了,所以必须要修改handlers.js文件以能够使页面正常运行

  3. 最终修改版汇总

  4.   1 function fileQueueError(file, errorCode, message) {
      2     try {
      3         var imageName = "error.gif";
      4         var errorName = "";
      5         if (errorCode == SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) {
      6             errorName = "上传文件过多!";
      7         }
      8
      9         if (errorName != "") {
     10             alert(errorName);
     11             return;
     12         }
     13
     14         switch (errorCode) {
     15         case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
     16             imageName = "zerobyte.gif";
     17             break;
     18         case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
     19             imageName = "toobig.gif";
     20             break;
     21         case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
     22         case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
     23         default:
     24             alert(message);
     25             break;
     26         }
     27         //添加图片,注意路径
     28         addImage("/swfupload/images/" + imageName);
     29
     30     } catch (ex) {
     31         this.debug(ex);
     32     }
     33
     34 }
     35
     36 function fileDialogComplete(numFilesSelected, numFilesQueued) {
     37     try {
     38         if (numFilesQueued > 0) {
     39             this.startUpload();
     40         }
     41     } catch (ex) {
     42         this.debug(ex);
     43     }
     44 }
     45
     46 function uploadProgress(file, bytesLoaded) {
     47
     48     try {
     49         var percent = Math.ceil((bytesLoaded / file.size) * 100);
     50
     51         var progress = new FileProgress(file,  this.customSettings.upload_target);
     52         progress.setProgress(percent);
     53         if (percent === 100) {
     54             progress.setStatus("正在创建缩略图...");
     55             progress.toggleCancel(false, this);
     56         } else {
     57             progress.setStatus("正在上传...");
     58             progress.toggleCancel(true, this);
     59         }
     60     } catch (ex) {
     61         this.debug(ex);
     62     }
     63 }
     64
     65 function uploadSuccess(file, serverData) {
     66     try {
     67         //添加缩略图~~~
     68         addImage("/Handlers/GetThumbHandler.ashx?id=" + serverData);
     69
     70         var progress = new FileProgress(file,  this.customSettings.upload_target);
     71
     72         progress.setStatus("缩略图创建成功!");
     73         progress.toggleCancel(false);
     74     } catch (ex) {
     75         this.debug(ex);
     76     }
     77 }
     78
     79 function uploadComplete(file) {
     80     try {
     81         /*  I want the next upload to continue automatically so I‘ll call startUpload here */
     82         if (this.getStats().files_queued > 0) {
     83             this.startUpload();
     84         } else {
     85             var progress = new FileProgress(file,  this.customSettings.upload_target);
     86             progress.setComplete();
     87             progress.setStatus("图片上传成功");
     88             progress.toggleCancel(false);
     89         }
     90     } catch (ex) {
     91         this.debug(ex);
     92     }
     93 }
     94
     95 function uploadError(file, errorCode, message) {
     96     var imageName =  "error.gif";
     97     var progress;
     98     try {
     99         switch (errorCode) {
    100         case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
    101             try {
    102                 progress = new FileProgress(file,  this.customSettings.upload_target);
    103                 progress.setCancelled();
    104                 progress.setStatus("上传操作被取消");
    105                 progress.toggleCancel(false);
    106             }
    107             catch (ex1) {
    108                 this.debug(ex1);
    109             }
    110             break;
    111         case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
    112             try {
    113                 progress = new FileProgress(file,  this.customSettings.upload_target);
    114                 progress.setCancelled();
    115                 progress.setStatus("上传停止!");
    116                 progress.toggleCancel(true);
    117             }
    118             catch (ex2) {
    119                 this.debug(ex2);
    120             }
    121         case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
    122             imageName = "uploadlimit.gif";
    123             break;
    124         default:
    125             alert(message);
    126             break;
    127         }
    128
    129         addImage("/swfupload/images/" + imageName);
    130
    131     } catch (ex3) {
    132         this.debug(ex3);
    133     }
    134
    135 }
    136
    137 function addImage(src) {
    138     var newImg = document.createElement("img");
    139     newImg.style.margin = "5px";
    140     document.getElementById("thumbnails").appendChild(newImg);
    141     if (newImg.filters) {
    142         try {
    143             newImg.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 0;
    144         } catch (e) {
    145             // If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
    146             newImg.style.filter = ‘progid:DXImageTransform.Microsoft.Alpha(opacity=‘ + 0 + ‘)‘;
    147         }
    148     } else {
    149         newImg.style.opacity = 0;
    150     }
    151
    152     newImg.onload = function () {
    153         fadeIn(newImg, 0);
    154     };
    155     newImg.src = src;
    156 }
    157
    158 function fadeIn(element, opacity) {
    159     var reduceOpacityBy = 5;
    160     var rate = 30;    // 15 fps
    161
    162
    163     if (opacity < 100) {
    164         opacity += reduceOpacityBy;
    165         if (opacity > 100) {
    166             opacity = 100;
    167         }
    168
    169         if (element.filters) {
    170             try {
    171                 element.filters.item("DXImageTransform.Microsoft.Alpha").opacity = opacity;
    172             } catch (e) {
    173                 // If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
    174                 element.style.filter = ‘progid:DXImageTransform.Microsoft.Alpha(opacity=‘ + opacity + ‘)‘;
    175             }
    176         } else {
    177             element.style.opacity = opacity / 100;
    178         }
    179     }
    180
    181     if (opacity < 100) {
    182         setTimeout(function () {
    183             fadeIn(element, opacity);
    184         }, rate);
    185     }
    186 }
    187
    188 /* ******************************************
    189  *    FileProgress Object
    190  *    Control object for displaying file info
    191  * ****************************************** */
    192
    193 function FileProgress(file, targetID) {
    194     this.fileProgressID = "divFileProgress";
    195
    196     this.fileProgressWrapper = document.getElementById(this.fileProgressID);
    197     if (!this.fileProgressWrapper) {
    198         this.fileProgressWrapper = document.createElement("div");
    199         this.fileProgressWrapper.className = "progressWrapper";
    200         this.fileProgressWrapper.id = this.fileProgressID;
    201
    202         this.fileProgressElement = document.createElement("div");
    203         this.fileProgressElement.className = "progressContainer";
    204
    205         var progressCancel = document.createElement("a");
    206         progressCancel.className = "progressCancel";
    207         progressCancel.href = "#";
    208         progressCancel.style.visibility = "hidden";
    209         progressCancel.appendChild(document.createTextNode(" "));
    210
    211         var progressText = document.createElement("div");
    212         progressText.className = "progressName";
    213         progressText.appendChild(document.createTextNode(file.name));
    214
    215         var progressBar = document.createElement("div");
    216         progressBar.className = "progressBarInProgress";
    217
    218         var progressStatus = document.createElement("div");
    219         progressStatus.className = "progressBarStatus";
    220         progressStatus.innerHTML = "&nbsp;";
    221
    222         this.fileProgressElement.appendChild(progressCancel);
    223         this.fileProgressElement.appendChild(progressText);
    224         this.fileProgressElement.appendChild(progressStatus);
    225         this.fileProgressElement.appendChild(progressBar);
    226
    227         this.fileProgressWrapper.appendChild(this.fileProgressElement);
    228
    229         document.getElementById(targetID).appendChild(this.fileProgressWrapper);
    230         fadeIn(this.fileProgressWrapper, 0);
    231
    232     } else {
    233         this.fileProgressElement = this.fileProgressWrapper.firstChild;
    234         this.fileProgressElement.childNodes[1].firstChild.nodeValue = file.name;
    235     }
    236
    237     this.height = this.fileProgressWrapper.offsetHeight;
    238
    239 }
    240 FileProgress.prototype.setProgress = function (percentage) {
    241     this.fileProgressElement.className = "progressContainer green";
    242     this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
    243     this.fileProgressElement.childNodes[3].style.width = percentage + "%";
    244 };
    245 FileProgress.prototype.setComplete = function () {
    246     this.fileProgressElement.className = "progressContainer blue";
    247     this.fileProgressElement.childNodes[3].className = "progressBarComplete";
    248     this.fileProgressElement.childNodes[3].style.width = "";
    249
    250 };
    251 FileProgress.prototype.setError = function () {
    252     this.fileProgressElement.className = "progressContainer red";
    253     this.fileProgressElement.childNodes[3].className = "progressBarError";
    254     this.fileProgressElement.childNodes[3].style.width = "";
    255
    256 };
    257 FileProgress.prototype.setCancelled = function () {
    258     this.fileProgressElement.className = "progressContainer";
    259     this.fileProgressElement.childNodes[3].className = "progressBarError";
    260     this.fileProgressElement.childNodes[3].style.width = "";
    261
    262 };
    263 FileProgress.prototype.setStatus = function (status) {
    264     this.fileProgressElement.childNodes[2].innerHTML = status;
    265 };
    266 FileProgress.prototype.toggleCancel = function (show, swfuploadInstance) {
    267     this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
    268     if (swfuploadInstance) {
    269         var fileID = this.fileProgressID;
    270         this.fileProgressElement.childNodes[0].onclick = function () {
    271             swfuploadInstance.cancelUpload(fileID);
    272             return false;
    273         };
    274     }
    275 };

    handlers.js

     1 <!DOCTYPE html>
     2
     3 <html xmlns="http://www.w3.org/1999/xhtml">
     4 <head runat="server">
     5     <title>Upload Images</title>
     6     <script src="swfupload/swfupload.js"></script>
     7     <script src="swfupload/handlers.js"></script>
     8     <script>
     9         //注:div的id名称最好不要改,要改的话在handlers.js文件中也要进行修改,div的名称已经在handlers.js文件中写死
    10         var swfu;
    11         window.onload = function () {
    12             swfu = new SWFUpload({
    13                 // 后台设置,设置处理上传的页面
    14                 upload_url: "/Handlers/ImageUploadHandler.ashx",
    15                 // 文件上传大小限制设置
    16                 file_size_limit: "3 MB",
    17                 //文件类型设置,多种格式以英文中的分号分开
    18                 file_types: "*.jpg;*.png",
    19                 //文件描述,与弹出的选择文件对话框相关
    20                 file_types_description : "Images file",
    21                 //设置上传文件数量限制
    22                 file_upload_limit: "1",
    23
    24                 //事件处理程序,最好不要改,事件处理程序已在handlers.js文件中定义
    25                 // Event Handler Settings - these functions as defined in Handlers.js
    26                 //  The handlers are not part of SWFUpload but are part of my website and control how
    27                 //  my website reacts to the SWFUpload events.
    28                 file_queue_error_handler : fileQueueError,
    29                 file_dialog_complete_handler : fileDialogComplete,
    30                 upload_progress_handler : uploadProgress,
    31                 upload_error_handler : uploadError,
    32                 upload_success_handler : uploadSuccess,
    33                 upload_complete_handler : uploadComplete,
    34
    35                 // 上传按钮设置
    36                 button_image_url : "/swfupload/images/XPButtonNoText_160x22.png",
    37                 button_placeholder_id: "spanButtonPlaceholder",
    38                 button_width: 160,
    39                 button_height: 22,
    40                 button_text : ‘请选择图片 (最大3M)‘,
    41                 button_text_style : ‘.button { font-family: Helvetica, Arial, sans-serif; font-size: 14pt; } .buttonSmall { font-size: 10pt; }‘,
    42                 button_text_top_padding: 1,
    43                 button_text_left_padding: 5,
    44
    45                 // swfupload.swf flash设置
    46                 flash_url : "/swfupload/swfupload.swf",
    47                 //自定义的其他设置
    48                 custom_settings : {
    49                     upload_target: "divFileProgressContainer"
    50                 },
    51                 // 是否开启调试模式,调试时可以设置为true,发布时设置为false
    52                 debug: false
    53             });
    54         }
    55     </script>
    56 </head>
    57 <body>
    58     <form id="form1" runat="server">
    59         <div id="content">
    60                 <h2>Upload Images Demo</h2>
    61
    62         <div id="swfu_container" style="margin: 0px 10px;">
    63             <div>
    64                 <span id="spanButtonPlaceholder"></span>
    65             </div>
    66             <div id="divFileProgressContainer" style="height: 75px;"></div>
    67             <div id="thumbnails"></div>
    68         </div>
    69         </div>
    70     </form>
    71 </body>
    72 </html>

    html Demo

      1 public class ImageUploadHandler : IHttpHandler, IRequiresSessionState
      2     {
      3         private static Common.LogHelper logger = new Common.LogHelper(typeof(ImageUploadHandler));
      4         public void ProcessRequest(HttpContext context)
      5         {
      6             context.Response.ContentType = "text/plain";
      7             System.Drawing.Image thumbnail_image = null;
      8             System.Drawing.Image original_image = null;
      9             System.Drawing.Bitmap final_image = null;
     10             System.Drawing.Graphics graphic = null;
     11             MemoryStream ms = null;
     12             try
     13             {
     14                 if (context.Session["User"]==null)
     15                 {
     16                     context.Response.Write("没有上传图片的权限!");
     17                     context.Response.End();
     18                     return;
     19                 }
     20                 // Get the data
     21                 HttpPostedFile image_upload = context.Request.Files["Filedata"];
     22                 //获取文件扩展名
     23                 string fileExt = System.IO.Path.GetExtension(image_upload.FileName).ToLower();
     24
     25                 //判断文件扩展名是否符合要求
     26                 if (fileExt!=".jpg"&&fileExt!=".png")
     27                 {
     28                     return;
     29                 }
     30                 string contentType = (fileExt == ".jpg" ? "image/jpeg" : "image/png");
     31                 //当前时间字符串
     32                 string timeString = DateTime.Now.ToString("yyyyMMddHHmmssfff");
     33                 string path = "/Upload/"+timeString + fileExt;
     34                 context.Session["imgPath"] = path;
     35                 //获取、构建要上传文件的物理路径
     36                 string serverPath = context.Server.MapPath("~/"+path);
     37                 //保存到服务器
     38                 image_upload.SaveAs(serverPath);
     39                 //记录日志
     40                 logger.Debug("图片上传成功!");
     41                 #region 生成缩略图
     42
     43                 // Retrieve the uploaded image
     44                 original_image = System.Drawing.Image.FromStream(image_upload.InputStream);
     45
     46                 // Calculate the new width and height
     47                 int width = original_image.Width;
     48                 int height = original_image.Height;
     49                 int target_width = 100;
     50                 int target_height = 100;
     51                 int new_width, new_height;
     52
     53                 float target_ratio = (float)target_width / (float)target_height;
     54                 float image_ratio = (float)width / (float)height;
     55
     56                 if (target_ratio > image_ratio)
     57                 {
     58                     new_height = target_height;
     59                     new_width = (int)Math.Floor(image_ratio * (float)target_height);
     60                 }
     61                 else
     62                 {
     63                     new_height = (int)Math.Floor((float)target_width / image_ratio);
     64                     new_width = target_width;
     65                 }
     66
     67                 new_width = new_width > target_width ? target_width : new_width;
     68                 new_height = new_height > target_height ? target_height : new_height;
     69
     70                 // Create the thumbnail
     71
     72                 final_image = new System.Drawing.Bitmap(target_width, target_height);
     73                 graphic = System.Drawing.Graphics.FromImage(final_image);
     74                 graphic.FillRectangle(new System.Drawing.SolidBrush(System.Drawing.Color.Black), new System.Drawing.Rectangle(0, 0, target_width, target_height));
     75                 int paste_x = (target_width - new_width) / 2;
     76                 int paste_y = (target_height - new_height) / 2;
     77                 graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; /* new way */
     78                                                                                                            //graphic.DrawImage(thumbnail_image, paste_x, paste_y, new_width, new_height);
     79                 graphic.DrawImage(original_image, paste_x, paste_y, new_width, new_height);
     80
     81                 // Store the thumbnail in the session (Note: this is bad, it will take a lot of memory, but this is just a demo)
     82                 ms = new MemoryStream();
     83                 final_image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
     84
     85                 #endregion
     86                 // Store the data in my custom Thumbnail object
     87                 string thumbnail_id = timeString;
     88                 Thumbnail thumb = new Thumbnail(thumbnail_id, ms.GetBuffer()) { ContentType= contentType };
     89                 context.Session["file_info"] = thumb;
     90                 context.Response.StatusCode = 200;
     91                 context.Response.Write(thumb.ID);
     92             }
     93             catch(Exception ex)
     94             {
     95                 // If any kind of error occurs return a 500 Internal Server error
     96                 context.Response.StatusCode = 500;
     97                 logger.Error(ex);
     98             }
     99             finally
    100             {
    101                 // Diospose
    102                 if (final_image != null) final_image.Dispose();
    103                 if (graphic != null) graphic.Dispose();
    104                 if (original_image != null) original_image.Dispose();
    105                 if (thumbnail_image != null) thumbnail_image.Dispose();
    106                 if (ms != null) ms.Close();
    107                 context.Response.End();
    108             }
    109         }
    110
    111         public bool IsReusable
    112         {
    113             get
    114             {
    115                 return false;
    116             }
    117         }
    118     }

    ImageUploadHandler

     1 public class GetThumbHandler : IHttpHandler, IRequiresSessionState
     2     {
     3
     4         public void ProcessRequest(HttpContext context)
     5         {
     6             context.Response.ContentType = "text/plain";
     7             string id = context.Request.QueryString["id"];
     8             if (id == null)
     9             {
    10                 context.Response.StatusCode = 404;
    11                 context.Response.Write("Not Found");
    12                 context.Response.End();
    13                 return;
    14             }
    15
    16             Thumbnail thumb= context.Session["file_info"] as Thumbnail;
    17             if (thumb.ID == id)
    18             {
    19                 context.Response.ContentType = thumb.ContentType;
    20                 context.Response.BinaryWrite(thumb.Data);
    21                 context.Response.End();
    22                 return;
    23             }
    24
    25             //没有找到相应图片,返回404
    26             context.Response.StatusCode = 404;
    27             context.Response.Write("Not Found");
    28             context.Response.End();
    29         }
    30
    31         public bool IsReusable
    32         {
    33             get
    34             {
    35                 return false;
    36             }
    37         }
    38     }

    GetThumbHandler

     1 /// <summary>
     2 /// 缩略图
     3 /// </summary>
     4 public class Thumbnail
     5 {
     6     public Thumbnail(string id, byte[] data)
     7     {
     8         this.ID = id;
     9         this.Data = data;
    10     }
    11
    12     private string id;
    13     public string ID
    14     {
    15         get
    16         {
    17             return this.id;
    18         }
    19         set
    20         {
    21             this.id = value;
    22         }
    23     }
    24
    25     private byte[] thumbnail_data;
    26     public byte[] Data
    27     {
    28         get
    29         {
    30             return this.thumbnail_data;
    31         }
    32         set
    33         {
    34             this.thumbnail_data = value;
    35         }
    36     }
    37
    38     private string contentType;
    39     public string ContentType
    40     {
    41         get
    42         {
    43             return contentType;
    44         }
    45
    46         set
    47         {
    48             contentType = value;
    49         }
    50     }
    51 }

    Thumbnail

时间: 2024-09-30 23:04:32

使用SWFUpload组件无刷新上传图片的相关文章

MVC无刷新上传图片并显示

@{ ViewBag.Title = "Home Page"; } <script src="../../Scripts/swfobject.js" type="text/javascript"></script> <script src="../../Scripts/jquery.uploadify.v2.1.4.js" type="text/javascript">&

无刷新上传图片,ajax 和 iframe

iframe 上传 upload.html <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title>     <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js">

JAVA servlet无刷新上传图片文件并裁剪demo代码(Jcrop)

原文:JAVA servlet无刷新上传图片文件并裁剪demo代码(Jcrop) 源代码下载地址:http://www.zuidaima.com/share/1550463770102784.htm sevlet写的demo,可直接运行.   

javascript 无刷新上传图片之原理

刚开始我认为可以像ajax 那样获取到数据然后通过ajax 发送请求,后来发现浏览器为了客户端的安全默认并没有给javascript 这个权限.这个方法当然是行不同了.我看了好像开源的上传图片原理,当然大部分是flash.但是为了方便使用js的也不少. 原理都是使用iframe 上传,在from标签里面有个属性 和a 标签一样 target,target标示这个表单的数据提交的目的地.网页特效代码target里面写iframe的name ,这样表单的数据就提交到了这个 iframe里面.根据这个

(iframe实现)无刷新上传图片

Index.aspx 页面 <html> <head> <title>iframe实现无刷新上传图片</title> </head> <body> <input id="photo" name="photo" type="text" style="display: none" /> <iframe id="upfile1&quo

表单无刷新上传图片

近期做有关上传图片的项目,发现都没有使用无刷新页面上传方式,都是通过传统的上传图片跳转然后显示图片,这对于上传多张图片就太不适用! 网上也有各种异步上传的插件 如 swfupload等比较庞大的插件,利用flash上传,顺带介绍一个比较简洁的ajax上传图片的插件ajaxFileUpload: 直接上地址:http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html 现在普通上传方式上改造一下,实现无刷新上传 通过隐藏ifram

Ajax 无刷新上传图片

如果用ajax直接传图片后台不好接受,所以最终还是要通过ajax来实现,原理很简单,触发form的submit()就可以了 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>无标题页</title> <script src="js/jquery-1.4.4.min.js" type="text/

移动端web无刷新上传图片【兼容安卓IOS】

需求 手机端网页或者微信无刷新上传头像 环境 手机浏览器或者微信浏览器(支持HTML5) 实现方式 LocalResizeIMG 地址 https://github.com/think2011/LocalResizeIMG(原版地址) 链接: http://pan.baidu.com/s/1ntNYXrb 密码: 71cp(个人修改版) 说明 原版只能指定固定的图片宽度,而修改版扩展原图片上传 使用方式 <h1 class="text-center">LocalResize

无刷新上传图片以及使用C#语言

写这个纯属是给自己一个记忆啦 一.前台的代码以及调用的js <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>上传</title> <s