双核浏览器下在chrome内核中使用uploadify总有302问题,也不知道如何修复,之所以喜欢360浏览器是因为帮客户控制渲染内核:
若页面需默认用极速核,增加标签:<meta name="renderer" content="webkit"/>
若页面需默认用ie兼容内核,增加标签:<meta name="renderer" content="ie-comp"/>
若页面需默认用ie标准内核,增加标签:<meta name="renderer" content="ie-stand"/> 要解决
302问题也很简单,就是html5的文件上传,正好最近在ueditor里看到百度的webuploader,会自动选择flash html5,就是一个成熟的解决方案了。
先看前端,我们将最常用的操作封装为插件,asp.net中和MVC中最好使用相对于应用程序的绝对路径,自行定义全局applicationPath :
var applicationPath = "@(Href("~")=="/"?"":Href("~"))"; 前端插件代码:
(function ($, window) { var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../.."; function S4() { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); } function initWebUpload(item, options) { if (!WebUploader.Uploader.support()) { var error = "上传控件不支持您的浏览器!请尝试升级flash版本或者使用Chrome引擎的浏览器。<a target="_blank" href="http://se.360.cn">下载页面</a>"; if (window.console) {window.console.log(error); } $(item).text(error); return;} var defaults = { hiddenInputId: "uploadifyHiddenInputId", // input hidden id onAllComplete: function (event) { }, // 当所有file都上传后执行的回调函数 onComplete: function (event) { },// 每上传一个file的回调函数 innerOptions: {}, fileNumLimit: undefined, fileSizeLimit: undefined, fileSingleSizeLimit: undefined, PostbackHold: false}; var opts = $.extend({}, defaults, options);var hdFileData = $("#" + opts.hiddenInputId); var target = $(item);//容器var pickerid = "";if (typeof guidGenerator36 != "undefined")//给一个唯一ID pickerid = guidGenerator36();else pickerid = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); var uploaderStrdiv = "<div class="webuploader">" + "<div id="thelist" class="uploader-list"></div>" + "<div class="btns">" + "<div id="" + pickerid + "">选择文件</div>" + //"<a id="ctlBtn" class="btn btn-default">开始上传</a>" + "</div>" +"</div>";target.append(uploaderStrdiv); var $list = target.find("#thelist"),$btn = target.find("#ctlBtn"),//这个留着,以便随时切换是否要手动上传state = "pending",uploader; var jsonData = { fileList: []}; var webuploaderoptions = $.extend({// swf文件路径 swf: applicationPath + "/Scripts/lib/webuploader/Uploader.swf",// 文件接收服务端。 server: applicationPath + "/MvcPages/WebUploader/Process",// 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: "#" + pickerid,// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! resize: false, fileNumLimit: opts.fileNumLimit, fileSizeLimit: opts.fileSizeLimit, fileSingleSizeLimit: opts.fileSingleSizeLimit},opts.innerOptions);var uploader = WebUploader.create(webuploaderoptions); //回发时还原hiddenfiled的保持数据 var fileDataStr = hdFileData.val(); if (fileDataStr && opts.PostbackHold) { jsonData = JSON.parse(fileDataStr); $.each(jsonData.fileList, function (index, fileData) { var newid = S4(); fileData.queueId = newid; $list.append("<div id="" + newid + "" class="item">" + "<div class="info">" + fileData.name + "</div>" + "<div class="state">已上传</div>" + "<div class="del"></div>" + "</div>"); }); hdFileData.val(JSON.stringify(jsonData)); } uploader.on("fileQueued", function (file) {//队列事件 $list.append("<div id="" + file.id + "" class="item">" +"<div class="info">" + file.name + "</div>" +"<div class="state">等待上传...</div>" +"<div class="del"></div>" + "</div>");});uploader.on("uploadProgress", function (file, percentage) {//进度条事件 var $li = target.find("#" + file.id),$percent = $li.find(".progress .bar");// 避免重复创建 if (!$percent.length) {$percent = $("<span class="progress">" + "<span class="percentage"><span class="text"></span>" + "<span class="bar" role="progressbar" style="width: 0%">" + "</span></span>" +"</span>").appendTo($li).find(".bar"); }$li.find("div.state").text("上传中"); $li.find(".text").text(Math.round(percentage * 100) + "%"); $percent.css("width", percentage * 100 + "%");});uploader.on("uploadSuccess", function (file, response) {//上传成功事件 target.find("#" + file.id).find("div.state").text("已上传"); var fileEvent = {queueId: file.id,name: file.name,size: file.size,type: file.type,filePath: response.filePath }; jsonData.fileList.push(fileEvent) opts.onComplete(fileEvent); }); uploader.on("uploadError", function (file) { target.find("#" + file.id).find("div.state").text("上传出错");}); uploader.on("uploadComplete", function (file) {//全部完成事件 target.find("#" + file.id).find(".progress").fadeOut(); var fp = $("#" + opts.hiddenInputId); fp.val(JSON.stringify(jsonData)); opts.onAllComplete(jsonData.fileList);}); uploader.on("fileQueued", function (file) { uploader.upload();}); uploader.on("filesQueued", function (file) { uploader.upload();}); uploader.on("all", function (type) { if (type === "startUpload") {state = "uploading"; } else if (type === "stopUpload") {state = "paused"; } else if (type === "uploadFinished") {state = "done"; }if (state === "uploading") {$btn.text("暂停上传"); } else {$btn.text("开始上传"); }}); $btn.on("click", function () { if (state === "uploading") {uploader.stop(); } else {uploader.upload(); }});//删除$list.on("click", ".del", function () { var $ele = $(this); var id = $ele.parent().attr("id"); var deletefile = {}; $.each(jsonData.fileList, function (index, item) {if (item && item.queueId === id) { uploader.removeFile(uploader.getFile(id));//不要遗漏 deletefile = jsonData.fileList.splice(index, 1)[0]; $("#" + opts.hiddenInputId).val(JSON.stringify(jsonData)); $.post(applicationi + "/Webploader/Delete", { "filepathname": deletefile.filePath }, function (returndata) {$ele.parent().remove(); }); return;} });});} $.fn.powerWebUpload = function (options) {var ele = this;if (typeof PowerJs != "undefined") { $.lazyLoad(applicationPath + "/Scripts/lib/webuploader/webuploader.css", function () { }, "css"); $.lazyLoad(applicationPath + "/Scripts/lib/webuploader/webuploader.min.js", function () {initWebUpload(ele, options); });}else { initWebUpload(ele, options);} }})(jQuery, window);
页面引入上述js后使用:
$("#uploader").powerWebUpload({ hiddenInputId: "uploadhidden" }); html端需要一个容器和hidden
<div id="uploader"></div><asp:HiddenField ID="hfFilePath" ClientIDMode="Static" runat="server" />
MVC版后端文件接收,即便你是asp.net 引入mvc做ajax也是可以的:
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Web;using System.Web.Mvc;public class WebUploaderController : BaseController {public ActionResult Process(string id, string name, string type, string lastModifiedDate, int size, HttpPostedFileBase file){ string filePathName = string.Empty;string localPath = Path.Combine(HttpRuntime.AppDomainAppPath, "Upload\Document"); if (Request.Files.Count == 0) {return Json(new { jsonrpc = 2.0, error = new { code = 102, message = "保存失败" }, id = "id" }); } try {filePathName = //自己在这里处理文件保存并返回需要保存到hidden的数据,文件在file或者Request.Files[0] } catch (Exception) {return Json(new { jsonrpc = 2.0, error = new { code = 103, message = "保存失败" }, id = "id" }); } return Json(new {jsonrpc = "2.0",id = "id",filePath = urlPath + "/" + filePathName });} static string urlPath = "../../Upload/Document"; public ActionResult Delete(string filePathName){ if (string.IsNullOrEmpty(filePathName)) {return Content("no"); } //为了安全 检查一下路径 不够严谨 自行更具业务做更加细致的判断 if (!filePathName.StartsWith(urlPath) ||filePathName.Substring(6, filePathName.Length - 7).Contains("../")) {return Content("no!"); } string localFilePathName = this.Server.MapPath(filePathName);try {bool b = UploadifyManager.DeleteAttachment(localFilePathName);if (!b) throw new Exception("删除文件失败"); return Content("ok"); } catch {return Content("no"); }} }
一开始发首页被退下来了,现在重新编辑使内容更加完整,优化了插件代码
完整demo: https://github.com/gxrsprite/AspnetMvcWebuploaderDemo
补充:扩展自定义参数,利用uploadBeforeSend事件可以扩展参数,插件内可根据需要修改。
cookie的问题,我用微软自带的登录系统,不需要做任何特殊处理完全没有问题。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。