雙核浏覽器下在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的問題,我用微軟自帶的登錄系統,不需要做任何特殊處理完全沒有問題。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。