項目中用到的幾個文件上傳的例子,記錄下,省得之後重複查找。javascript
一、html5文件上傳css
之前上傳文件須要提交Form表單。
HTML5方式上傳文件,能夠經過使用FormData類模擬Form表單提交,從而實現無刷新上傳文件。html
假設有一個文件選擇框html5
<input id="chooseImage" type="file" style="display: none">java
能夠在html中另外寫一個dom來觸發文件選擇,或者直接使用文件選擇也能夠(醜一點)jquery
<style> .upload_img { width: 80px; height: 80px; background-color: #fff; color: green; border: 1px solid green; border-radius: 5px; text-align: center; line-height: 80px; font-size: 40px; background-position: center; background-size: contain; cursor: pointer; } </style> <div class="form-group cell_upload"> <label class="col-sm-4 control-label no-padding-right" for="pname"><span class="lbl-warning">*</span> 轉讓文件 </label> <div class="col-sm-4"> <div class="upload_img" style="background-image: url("");">+</div> </div> <div class="col-sm-4"> <div class="upload_ready"></div> </div> </div> $(function () { $('.cell_upload .upload_img').click(function () { $('#chooseImage').click();//激活圖片上傳 }); })
選擇XMLHttpRequest方式上傳(有進度事件)git
//圖片上傳 $("#chooseImage").change(function () { var file = $(this)[0].files[0];//獲取files對象 //禁用提交按鈕 $('.btn-primary-transfer').attr('disabled', true); $('.btn-primary-transfer').css('background-color', '#ccc'); //顯示進度條 $('.cell_upload').after($('.progressbar')); $('.progressbar #sliderTrack').width('0%'); $('.progressbar #sliderHandler').css('left', '0%'); $('.progressbar #sliderValue').html('0%'); $('.progressbar').show(); var files = document.getElementById('chooseImage').files; //files是文件選擇框選擇的文件對象數組 if (files.length == 0) return; var form = new FormData(), url = '/DC/File/patent_transferUpload', //服務器上傳地址 file = files[0]; form.append('file', file); var xhr = new XMLHttpRequest(); xhr.open("post", url, true); //上傳進度事件 xhr.upload.addEventListener("progress", function (progress) { if (progress.lengthComputable) { //上傳進度 var prog = parseInt(progress.loaded / progress.total * 100); $('.progressbar #sliderTrack').width(prog + '%'); $('.progressbar #sliderHandler').css('left', prog + '%'); $('.progressbar #sliderValue').html(prog + '%'); } }, false); xhr.addEventListener("readystatechange", function () { var result = xhr; if (result.status != 200) { //error console.log('上傳失敗', result.status, result.statusText, result.response); } else if (result.readyState == 4) { //finished console.log('上傳成功', result); $('#btnSubmit').removeAttr('disabled'); $('#btnSubmit').css('background-color', '#1AAD19'); $('.progressbar').slideUp(); let resp = JSON.parse(result.response); if (resp.state) { $('#filepath').val(resp.filepath); $('#filename').val(resp.filename); let vfile = `<a href="${resp.filePath}" download="${resp.fileName}" target="_blank">${resp.fileName}</a>`; $('.cell_upload .upload_ready').html(vfile); $('.cell_upload .upload_img').html('✔'); } } }); xhr.send(form); //開始上傳 })
@*圖片上傳工具*@ <input id="chooseImage" type="file" style="display: none"> @*進度條*@ <div class="weui-cell progressbar"> @*<div class="weui-cell__hd"><label class="weui-label">進度</label></div>*@ <div class="weui-cell__bd"> <div class="weui-slider-box"> <div class="weui-slider"> <div id="sliderInner" class="weui-slider__inner" style="background-color: #aaa;"> <div id="sliderTrack" style="width: 0%;" class="weui-slider__track"></div> <div id="sliderHandler" style="left: 0%;" class="weui-slider__handler"></div> </div> </div> <div id="sliderValue" class="weui-slider-box__value">50</div> </div> </div> </div>
附加:另一種網友提供的方式,本身木有使用github
var form = new FormData(), url = 'http://.......', //服務器上傳地址 file = files[0]; form.append('file', file); fetch(url, { method: 'POST', body: form }).then(function(response) { if (response.status >= 200 && response.status < 300) { return response; } else { var error = new Error(response.statusText); error.response = response; throw error; } }).then(function(resp) { return resp.json(); }).then(function(respData) { console.log('文件上傳成功', respData); }).catch(function(e) { console.log('文件上傳失敗', e); }); --------------------- 做者:神祕_博士 來源:CSDN 原文:https://blog.csdn.net/lovelyelfpop/article/details/71421123 版權聲明:本文爲博主原創文章,轉載請附上博文連接!
後臺接收程序(項目使用的是.net mvc)web
public JsonResult patent_transferUpload() { string physicalFolderPath = string.Empty;//物理文件夾路徑 HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files; if (string.IsNullOrEmpty(this.demandFolderPath)) { // physicalFolderPath = Server.MapPath(@"\Files\DemandFiles"); physicalFolderPath = "/Files/patent_transfer"; } else { physicalFolderPath = this.demandFolderPath; } return Upload(hfc, physicalFolderPath, ""); } /// <summary> /// 保存文件 /// </summary> /// <param name="hfc">文件信息</param> /// <param name="physicalFolderPath">物理文件存儲文件夾絕對路徑</param> /// <returns></returns> private JsonResult Upload(HttpFileCollection hfc, string physicalFolderPath,string guid) { try { string msg = "位置錯誤!"; string physicalFullPath = string.Empty; string fileName = string.Empty; bool isSuccess = false; var files = Request.Files; if (guid == "") { guid = Guid.NewGuid().ToString(); } if (hfc != null && hfc.Count > 0) { try { fileName = hfc[0].FileName; if (!string.IsNullOrEmpty(fileName)) { string save_dir= Server.MapPath(physicalFolderPath); if (!Directory.Exists(save_dir)) { Directory.CreateDirectory(save_dir); } physicalFullPath = physicalFolderPath + "/" + guid + Path.GetExtension(fileName); string savepath = Server.MapPath(physicalFullPath) ; hfc[0].SaveAs(savepath); isSuccess = true; msg = "上傳成功!"; } else { msg = "未識別任何有效文件!"; } } catch (Exception e) { msg = e.Message; } } return Json(new { state = isSuccess, message = msg,guid= guid, fileName = fileName, filePath = physicalFullPath }, JsonRequestBehavior.AllowGet); } catch { return Json(new { state = false, message = "上傳文件失敗!" }, JsonRequestBehavior.AllowGet); } }
引用:ajax
http://www.javashuo.com/article/p-hysbyiyu-x.html
*************************************************************** 華麗麗的分割線 ***************************************************************
2 移動端的圖片壓縮上傳(使用二進制數據流)
這是一個在微信公衆號開發中用到的圖片上傳
同1,在html中添加一個文件上傳的控件
<input id="chooseImage" type="file" style="display: none">
而後在寫一個控件來觸發文件上傳,同時爲上傳添加進度條顯示.progressbar
<style> .upload_img { width: 80px; height: 80px; background-color: #fff; color: green; border:1px solid green; border-radius: 5px; text-align: center; line-height: 80px; font-size: 40px; background-position:center; background-size:contain; } .upload_delete { display:none; width: 30px; height: 30px; background-color: orangered; color: #fff; border-radius: 50%; text-align: center; line-height: 30px; font-size: 24px; margin-left: 20px; } </style> <div > <div class="weui-cell__hd"><label class="weui-label"></label></div> <div class="weui-cell__bd cell_upload box-space-between" tag="2e89acb0-b36e-4934-9c31-f718aea815f9"> <div tag="" class="upload_img" style="background-image: url("");">+</div> <div tag="" class="upload_delete" style="display: none;">-</div> <input class="upload_save" id="" type="text" style="display:none;"> </div> </div> @*圖片上傳工具*@ <input id="chooseImage" type="file" style="display: none"> @*進度條*@ <div class="weui-cell progressbar"> @*<div class="weui-cell__hd"><label class="weui-label">進度</label></div>*@ <div class="weui-cell__bd"> <div class="weui-slider-box"> <div class="weui-slider"> <div id="sliderInner" class="weui-slider__inner" style="background-color: #aaa;"> <div id="sliderTrack" style="width: 0%;" class="weui-slider__track"></div> <div id="sliderHandler" style="left: 0%;" class="weui-slider__handler"></div> </div> </div> <div id="sliderValue" class="weui-slider-box__value">50</div> </div> </div> </div>
上傳限制了圖片的類型和大小
//圖片上傳 $("#chooseImage").change(function () { var file = $(this)[0].files[0];//獲取files對象 var rFilter = /^(image\/jpeg|image\/png)$/i; // 檢查圖片格式 if (!rFilter.test(file.type)) { wxAlert.showMsg('只能夠上傳.jpg/.jpeg/.png格式的圖片!'); return false; } if (file.size > 5000000) { wxAlert.showMsg('上傳圖片最大爲5M,請從新上傳!'); return false; } //禁用提交按鈕 $('#btnSubmit').attr('disabled', true); $('#btnSubmit').css('background-color', '#ccc'); //顯示進度條 $('.cell_upload').parent().after($('.progressbar')); $('.progressbar #sliderTrack').width('0%'); $('.progressbar #sliderHandler').css('left', '0%'); $('.progressbar #sliderValue').html('0%'); $('.progressbar').show(); //0.5爲當前壓縮比 var ratio = 1; if (file.size > 500000 && file.size <= 1000000) { ratio = 0.8;//0.5-1M壓縮比 } else if (file.size > 1000000 && file.size <= 2000000) { ratio = 0.7;//1-2M壓縮比 } else if (file.size > 2000000 && file.size <= 5000000) { ratio = 0.5;//2-5M壓縮比 } else if (file.size > 5000000 && file.size <= 10000000) { ratio = 0.4;//5-10M壓縮比 } file_compress(file, ratio); }) //壓縮文件並上傳 function file_compress(file, ratio) { $.compress(file, ratio).then((url) => { $('.upload_img').css({ "background-image": "url(" + url + ")" }); /*----------------上傳到服務器-----------------*/ var posturl = '/wechatPage/health_record/health_recordFile'; var filename = hr_type_selected + '_' + health_record_id + '_' + templateID_active;//文件名定義爲typeID+’_’+hrID+’_’+templateID.jpg var para = { imgbase: url, filename: filename }; $.ajax({ type: "POST", url: posturl, data: para, //這裏上傳的數據使用了formData 對象 xhr: function () { var xhr = $.ajaxSettings.xhr(); if (xhr.upload) { xhr.upload.onprogress = function (progress) { if (progress.lengthComputable) { //上傳進度 var prog = parseInt(progress.loaded / progress.total * 100); $('.progressbar #sliderTrack').width(prog + '%'); $('.progressbar #sliderHandler').css('left', prog + '%'); $('.progressbar #sliderValue').html(prog + '%'); } }; xhr.upload.onloadstart = function () { console.log('started...'); }; } return xhr; } }).done(function (resp) { //上傳完成 $('#btnSubmit').removeAttr('disabled'); $('#btnSubmit').css('background-color', '#1AAD19'); $('.progressbar').slideUp(); if (resp.state) { //do something } }).fail(function (err) { alert('沒法鏈接服務器!') }); }) }
壓縮處理圖片(需將此compress.js文件引用到html中)
compress.js 先建立了一塊畫布canvas,而後根據須要壓縮的程度,使用canvas進行畫圖,而後再將畫好的壓縮過的圖片轉化爲數據流返回,
resolve關鍵字可理解爲Promise的正確執行後的返回值。
Promise的then關鍵字便是接收resolve傳回的參數
(function ($) { $.extend({ //壓縮圖片,參數1:file對象,參數2:壓縮比例 compress(file, scale) { return new Promise(function (resolve, reject) { let _scale = scale || 1; let cvs = document.createElement('canvas'); let ctx = cvs.getContext('2d'); let img = new window.Image(); let imgType = file.type; img.src = URL.createObjectURL(file); img.onload = function () { cvs.width = img.width * _scale; cvs.height = img.height * _scale; EXIF.getData(img, function () { EXIF.getAllTags(this); var orient = EXIF.getTag(this, 'Orientation'); //alert('orient:' + orient); switch (orient) { case 3: ctx.rotate(180 * Math.PI / 180); ctx.drawImage(img, -cvs.width, -cvs.height, cvs.width, cvs.height); break; case 6: cvs.width = img.height * _scale; cvs.height = img.width * _scale; ctx.rotate(90 * Math.PI / 180); ctx.drawImage(img, 0, -cvs.width, cvs.height, cvs.width); break; case 8: ctx.rotate(270 * Math.PI / 180); ctx.drawImage(img, -cvs.height, 0, cvs.height, cvs.width); break; case 2: ctx.translate(cvs.width, 0); ctx.scale(-1, 1); ctx.drawImage(img, 0, 0, cvs.width, cvs.height); break; case 4: ctx.translate(cvs.width, 0); ctx.scale(-1, 1); ctx.rotate(180 * Math.PI / 180); ctx.drawImage(img, -cvs.width, -cvs.height, cvs.width, cvs.height); break; case 5: ctx.translate(cvs.width, 0); ctx.scale(-1, 1); ctx.rotate(90 * Math.PI / 180); ctx.drawImage(img, 0, -cvs.width, cvs.height, cvs.width); break; case 7: ctx.translate(cvs.width, 0); ctx.scale(-1, 1); ctx.rotate(270 * Math.PI / 180); ctx.drawImage(img, -cvs.height, 0, cvs.height, cvs.width); break; default: ctx.drawImage(img, 0, 0, cvs.width, cvs.height); } resolve(cvs.toDataURL(imgType)); }); } }); } }); })(jQuery)
期間遇到iphone手機直接拍攝圖片後上傳,圖片反轉90度的問題,在compress.js 獲取了文件的Orientation屬性
var orient = EXIF.getTag(this, 'Orientation');
能夠根據圖片的翻轉類型對圖片的反轉度進行調整。
後臺接收程序
/// <summary> /// 上傳健康檔案文件 /// </summary> /// <param name="imgbase">圖片數據流</param> /// <param name="filename">保存的圖片名</param> /// <returns></returns> [HttpPost] public ActionResult health_recordFile(string imgbase, string filename) { try { //保存目錄 string dir = "/Files/health_record"; //站點文件目錄 string fileDir = Server.MapPath("~" + dir); //保存文件所在站點位置 string filePath = Path.Combine(fileDir, filename); if (!System.IO.Directory.Exists(fileDir)) System.IO.Directory.CreateDirectory(fileDir); //將Base64String轉爲圖片並保存 // byte[] arr2 = Convert.FromBase64String(imgbase); byte[] arr2 = Convert.FromBase64String(imgbase.Substring(imgbase.IndexOf(',') + 1)); using (MemoryStream ms2 = new MemoryStream(arr2)) { System.Drawing.Bitmap bmp2 = new System.Drawing.Bitmap(ms2); bmp2.Save(filePath + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); bmp2.Dispose(); } var msg = new { state = true, msg = "上傳圖片成功!", imgsrc = dir + "/" + filename + "" + ".jpg" }; return Json(msg); } catch { var msg = new { state = false, msg = "上傳圖片失敗!", imgsrc = "" }; return Json(msg); } }
附:js中使用了Promise函數的簡介說明
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h4>Promise:把原來的回調寫法分離出來,在異步操做執行完後,用鏈式調用的方式執行回調函數</h4> <h5>resolve:將Promise的狀態置爲fullfiled,可理解爲成功回調</h5> <h5>reject:將Promise的狀態置爲rejected,可理解爲失敗回調</h5> <h5>then:then接收一個參數,是函數,而且會拿到咱們在runAsync中調用resolve時傳的的參數</h5> <h5>catch:catch接收一個參數,是函數,而且會拿到咱們在runAsync中調用reject時傳的的參數</h5> <h5>all:提供了並行執行異步操做的能力,而且在全部異步操做執行完後才執行回調「誰跑的慢,以誰爲準執行回調」</h5> <pre>all的使用場景1:一些遊戲類的素材比較多的應用,打開網頁時,預先加載須要用到的各類資源如圖片、flash以及各類靜態文件。全部的都加載完後,咱們再進行頁面的初始化。</pre> <pre>all的使用場景2:在較複雜的頁面,等全部的異步加載所有完成後,再渲染頁面。</pre> <h5>race:同all同樣提供並行操做的能力,區別是race執行標準是:[誰跑的快,以誰爲準執行回調]</h5> <pre>race使用場景:用race給某個異步請求設置超時時間,而且在超時後執行相應的操做(好比請求圖片時設置超時時間)</pre> <script type="text/javascript" src="../../script/jquery-1.8.3.min.js"></script> <script type="text/javascript"> $(function () { fun_01(); fun_02(); fun_03(); }) let fun_01=()=>{ console.log('---------- Promise01 ----------'); new Promise(test).then(function (result) { console.log('Success:'+result); }).catch(function (result) { console.log('Fail:'+result); }) }; function test(resolve,reject) { let timeout=Math.random()*2; console.log('set timeout to:'+timeout+' seconds'); setTimeout(function () { if(timeout<1){ console.log('call resolve()...'); resolve('200 OK'); }else{ console.log('call reject()...'); reject('timeout in '+timeout+' seconds'); } },timeout*1000); } let fun_02=()=>{ console.log('---------- Promise02 ----------'); runAsync().then(function (data) { console.log(data); }); runAsync1().then(function (data) { console.log(data); return runAsync2(); }).then(function (data) { console.log(data); return runAsync3(); }); setTimeout(runAll,5*1000); }; function runAll() { console.log('----------Promise.all----------'); //Promise的all方法提供了並行執行異步操做的能力,而且在全部異步操做執行完後才執行回調 Promise.all([runAsync1(),runAsync2(),runAsync3()]).then(function (result) { console.log(result); }) } function runAsync() { let p=new Promise(function (resolve,reject) { setTimeout(function () { console.log('timeout done!'); resolve(' anythind you want'); }) }) return p; } function runAsync1(){ var p = new Promise(function(resolve, reject){ //作一些異步操做 setTimeout(function(){ console.log('異步任務1執行完成'); resolve('隨便什麼數據1'); }, 1000); }); return p; } function runAsync2(){ var p = new Promise(function(resolve, reject){ //作一些異步操做 setTimeout(function(){ console.log('異步任務2執行完成'); resolve('隨便什麼數據2'); }, 1000); }); return p; } function runAsync3(){ var p = new Promise(function(resolve, reject){ //作一些異步操做 setTimeout(function(){ console.log('異步任務3執行完成'); resolve('隨便什麼數據3'); }, 1000); }); return p; } let fun_03=()=>{ console.log('---------- Promise03 ----------'); Promise .race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(reason){ console.log(reason); }); }; //請求某個圖片資源 function requestImg(){ var p = new Promise(function(resolve, reject){ var img = new Image(); img.onload = function(){ resolve(img); } img.src = 'xxxxxx'; }); return p; } //延時函數,用於給請求計時 function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('圖片請求超時'); }, 5000); }); return p; } </script> </body> </html>
*************************************************************** 華麗麗的分割線 ***************************************************************
3.dropzone文件上傳
官網:https://www.dropzonejs.com/
中文文檔:http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/#configuration
我的以爲比較好的一個上傳工具,經常使用的配置項和事件都很清楚,自帶多文件上傳和進度條,很贊。
很差的地方時,每一個頁面只能初始化一個dropzone,如遇到頁面嵌套的dom也須要上傳文件的狀況就處理不了了,目前木有解決,官方也木有聞文檔說明。
下面是須要引用的css文件(因爲在上傳單文件的時候,dropzone原來的上傳框頁面尺寸太大,我對css又作了一點調整,使其適合單獨放在頁面的dom中,因此本身記錄下)
固然原始文件官網均可如下載到
/* * The MIT License * Copyright (c) 2012 Matias Meno <m@tias.me> */ @-webkit-keyframes passing-through { 0% { opacity: 0; -webkit-transform: translateY(40px); -moz-transform: translateY(40px); -ms-transform: translateY(40px); -o-transform: translateY(40px); transform: translateY(40px); } 30%, 70% { opacity: 1; -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -ms-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); } 100% { opacity: 0; -webkit-transform: translateY(-40px); -moz-transform: translateY(-40px); -ms-transform: translateY(-40px); -o-transform: translateY(-40px); transform: translateY(-40px); } } @-moz-keyframes passing-through { 0% { opacity: 0; -webkit-transform: translateY(40px); -moz-transform: translateY(40px); -ms-transform: translateY(40px); -o-transform: translateY(40px); transform: translateY(40px); } 30%, 70% { opacity: 1; -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -ms-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); } 100% { opacity: 0; -webkit-transform: translateY(-40px); -moz-transform: translateY(-40px); -ms-transform: translateY(-40px); -o-transform: translateY(-40px); transform: translateY(-40px); } } @keyframes passing-through { 0% { opacity: 0; -webkit-transform: translateY(40px); -moz-transform: translateY(40px); -ms-transform: translateY(40px); -o-transform: translateY(40px); transform: translateY(40px); } 30%, 70% { opacity: 1; -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -ms-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); } 100% { opacity: 0; -webkit-transform: translateY(-40px); -moz-transform: translateY(-40px); -ms-transform: translateY(-40px); -o-transform: translateY(-40px); transform: translateY(-40px); } } @-webkit-keyframes slide-in { 0% { opacity: 0; -webkit-transform: translateY(40px); -moz-transform: translateY(40px); -ms-transform: translateY(40px); -o-transform: translateY(40px); transform: translateY(40px); } 30% { opacity: 1; -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -ms-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); } } @-moz-keyframes slide-in { 0% { opacity: 0; -webkit-transform: translateY(40px); -moz-transform: translateY(40px); -ms-transform: translateY(40px); -o-transform: translateY(40px); transform: translateY(40px); } 30% { opacity: 1; -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -ms-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); } } @keyframes slide-in { 0% { opacity: 0; -webkit-transform: translateY(40px); -moz-transform: translateY(40px); -ms-transform: translateY(40px); -o-transform: translateY(40px); transform: translateY(40px); } 30% { opacity: 1; -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -ms-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); } } @-webkit-keyframes pulse { 0% { -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); } 10% { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -ms-transform: scale(1.1); -o-transform: scale(1.1); transform: scale(1.1); } 20% { -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); } } @-moz-keyframes pulse { 0% { -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); } 10% { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -ms-transform: scale(1.1); -o-transform: scale(1.1); transform: scale(1.1); } 20% { -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); } } @keyframes pulse { 0% { -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); } 10% { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -ms-transform: scale(1.1); -o-transform: scale(1.1); transform: scale(1.1); } 20% { -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); } } .dropzone, .dropzone * { box-sizing: border-box; } .dropzone { width:110px; min-height: 90px; border: 2px solid rgba(0, 0, 0, 0.3); background: white; padding: 0px 0px; } .dropzone.dz-clickable { cursor: pointer; } .dropzone.dz-clickable * { cursor: default; } .dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * { cursor: pointer; } .dropzone.dz-started .dz-message { display: none; } .dropzone.dz-drag-hover { border-style: solid; } .dropzone.dz-drag-hover .dz-message { opacity: 0.5; } .dropzone .dz-message { text-align: center; } .dropzone .dz-preview { position: relative; display: inline-block; vertical-align: top; margin: 2px; min-height: 100px; } .dropzone .dz-preview:hover { z-index: 1000; } .dropzone .dz-preview:hover .dz-details { opacity: 1; } .dropzone .dz-preview.dz-file-preview .dz-image { border-radius: 20px; background: #999; background: linear-gradient(to bottom, #eee, #ddd); } .dropzone .dz-preview.dz-file-preview .dz-details { opacity: 1; } .dropzone .dz-preview.dz-image-preview { background: white; } .dropzone .dz-preview.dz-image-preview .dz-details { -webkit-transition: opacity 0.2s linear; -moz-transition: opacity 0.2s linear; -ms-transition: opacity 0.2s linear; -o-transition: opacity 0.2s linear; transition: opacity 0.2s linear; } .dropzone .dz-preview .dz-remove { font-size: 14px; text-align: center; display: block; cursor: pointer; border: none; } .dropzone .dz-preview .dz-remove:hover { text-decoration: underline; } .dropzone .dz-preview:hover .dz-details { opacity: 1; } .dropzone .dz-preview .dz-details { z-index: 20; position: absolute; top: 0; left: 0; opacity: 0; font-size: 13px; min-width: 100%; max-width: 100%; padding: 2em 1em; text-align: center; color: rgba(0, 0, 0, 0.9); line-height: 150%; } .dropzone .dz-preview .dz-details .dz-size { margin-bottom: 1em; font-size: 16px; } .dropzone .dz-preview .dz-details .dz-filename { white-space: nowrap; } .dropzone .dz-preview .dz-details .dz-filename:hover span { border: 1px solid rgba(200, 200, 200, 0.8); background-color: rgba(255, 255, 255, 0.8); } .dropzone .dz-preview .dz-details .dz-filename:not(:hover) { overflow: hidden; text-overflow: ellipsis; } .dropzone .dz-preview .dz-details .dz-filename:not(:hover) span { border: 1px solid transparent; } .dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span { background-color: rgba(255, 255, 255, 0.4); padding: 0 0.4em; border-radius: 3px; } .dropzone .dz-preview:hover .dz-image img { -webkit-transform: scale(1.05, 1.05); -moz-transform: scale(1.05, 1.05); -ms-transform: scale(1.05, 1.05); -o-transform: scale(1.05, 1.05); transform: scale(1.05, 1.05); -webkit-filter: blur(8px); filter: blur(8px); } .dropzone .dz-preview .dz-image { border-radius: 20px; overflow: hidden; width: 100px; height: 100px; position: relative; display: block; z-index: 10; } .dropzone .dz-preview .dz-image img { display: block; } .dropzone .dz-preview.dz-success .dz-success-mark { -webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); -moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); -ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); -o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); } .dropzone .dz-preview.dz-error .dz-error-mark { opacity: 1; -webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); -moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); -ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); -o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); } .dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark { pointer-events: none; opacity: 0; z-index: 500; position: absolute; display: block; top: 50%; left: 50%; margin-left: -27px; margin-top: -27px; } .dropzone .dz-preview .dz-success-mark svg, .dropzone .dz-preview .dz-error-mark svg { display: block; width: 54px; height: 54px; } .dropzone .dz-preview.dz-processing .dz-progress { opacity: 1; -webkit-transition: all 0.2s linear; -moz-transition: all 0.2s linear; -ms-transition: all 0.2s linear; -o-transition: all 0.2s linear; transition: all 0.2s linear; } .dropzone .dz-preview.dz-complete .dz-progress { opacity: 0; -webkit-transition: opacity 0.4s ease-in; -moz-transition: opacity 0.4s ease-in; -ms-transition: opacity 0.4s ease-in; -o-transition: opacity 0.4s ease-in; transition: opacity 0.4s ease-in; } .dropzone .dz-preview:not(.dz-processing) .dz-progress { -webkit-animation: pulse 6s ease infinite; -moz-animation: pulse 6s ease infinite; -ms-animation: pulse 6s ease infinite; -o-animation: pulse 6s ease infinite; animation: pulse 6s ease infinite; } .dropzone .dz-preview .dz-progress { opacity: 1; z-index: 1000; pointer-events: none; position: absolute; height: 16px; left: 50%; top: 50%; margin-top: -8px; width: 80px; margin-left: -40px; background: rgba(255, 255, 255, 0.9); -webkit-transform: scale(1); border-radius: 8px; overflow: hidden; } .dropzone .dz-preview .dz-progress .dz-upload { background: #333; background: linear-gradient(to bottom, #666, #444); position: absolute; top: 0; left: 0; bottom: 0; width: 0; -webkit-transition: width 300ms ease-in-out; -moz-transition: width 300ms ease-in-out; -ms-transition: width 300ms ease-in-out; -o-transition: width 300ms ease-in-out; transition: width 300ms ease-in-out; } .dropzone .dz-preview.dz-error .dz-error-message { display: block; } .dropzone .dz-preview.dz-error:hover .dz-error-message { opacity: 1; pointer-events: auto; } .dropzone .dz-preview .dz-error-message { pointer-events: none; z-index: 1000; position: absolute; display: block; display: none; opacity: 0; -webkit-transition: opacity 0.3s ease; -moz-transition: opacity 0.3s ease; -ms-transition: opacity 0.3s ease; -o-transition: opacity 0.3s ease; transition: opacity 0.3s ease; border-radius: 8px; font-size: 13px; top: 130px; left: -10px; width: 110px; background: #be2626; background: linear-gradient(to bottom, #be2626, #a92222); padding: 0.5em 1.2em; color: white; } .dropzone .dz-preview .dz-error-message:after { content: ''; position: absolute; top: -6px; left: 64px; width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid #be2626; }
》須要引用的文件
<link rel="stylesheet" href="~/assets/dropzone/dist/dropzone.css" />
<script type="text/javascript" src="~/assets/dropzone/dist/dropzone.js"></script>
html中定義class爲dropzone的dom,做爲上傳控件
<div class="dropzone" id="my-dropzone"></div>
//Dropzone的初始化 Dropzone.options.myDropzone = { //指定上傳圖片的路徑 url: '/DC/File/ReportFileUpload', method: "post", //也可用put paramName: "file", //默認爲file maxFiles: 1,//一次性上傳的文件數量上限 maxFilesize: 10, //文件大小,單位:MB acceptedFiles: "*", //上傳的類型 addRemoveLinks: true, //添加上傳取消和刪除預覽圖片的連接,默認不添加 autoProcessQueue: true,//關閉自動上傳功能,默認會true會自動上傳 uploadMultiple: false,//容許上傳多個照片 parallelUploads: 1,//每次上傳的最多文件數,經測試默認爲2,坑啊,記得修改web.config 限制上傳文件大小的節 dictDefaultMessage: '拖動文件至此或者點擊上傳', dictMaxFilesExceeded: "您最多隻能上傳1個文件!", dictResponseError: '文件上傳失敗!', dictInvalidFileType: "", dictFallbackMessage: "瀏覽器不受支持", dictFileTooBig: "文件過大上傳文件最大支持.", dictRemoveLinks: "刪除", dictCancelUpload: "取消", init: function () { myDropzone = this; // closure this.on("addedfile", function () { this.options.headers = { "id": $('#ID').val() }; $('.modal-dialog .btn-primary').attr("disabled", true); }); //當上傳完成後的事件,接受的數據爲JSON格式 this.on("complete", function (data) { $('.modal-dialog .btn-primary').removeAttr("disabled"); if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) { // var res = eval('(' + data.xhr.responseText + ')'); var res = JSON.parse(data.xhr.responseText) if (res.state) { //do something } else { CM.showMsg('上傳文件失敗!'); } } }); //刪除圖片的事件,當上傳的圖片爲空時,使上傳按鈕不可用狀態 this.on("removedfile", function () { if (this.getAcceptedFiles().length === 0) { $("#filename").val(''); $("#filepath").val(''); } }); } }; function removeDropzoneFile() { //去除Dropzone已經存在的圖片 if (!CM.isNull(myDropzone) && myDropzone.files.length != 0) { for (var i = 0; i < myDropzone.files.length; i++) { myDropzone.removeFile(myDropzone.files[0]); } } }
後臺的接收方法
public JsonResult ReportFileUpload() { string physicalFolderPath = string.Empty;//物理文件夾路徑 HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files; if (string.IsNullOrEmpty(this.reportFolderPath)) { // physicalFolderPath = Server.MapPath(@"\Files\ReportFiles"); physicalFolderPath = "/Files/ReportFiles"; } else { physicalFolderPath = this.reportFolderPath; } return Upload(hfc, physicalFolderPath,""); } /// <summary> /// 保存文件 /// </summary> /// <param name="hfc">文件信息</param> /// <param name="physicalFolderPath">物理文件存儲文件夾絕對路徑</param> /// <returns></returns> private JsonResult Upload(HttpFileCollection hfc, string physicalFolderPath,string guid) { try { string msg = "位置錯誤!"; string physicalFullPath = string.Empty; string fileName = string.Empty; bool isSuccess = false; var files = Request.Files; if (guid == "") { guid = Guid.NewGuid().ToString(); } if (hfc != null && hfc.Count > 0) { try { fileName = hfc[0].FileName; if (!string.IsNullOrEmpty(fileName)) { string save_dir= Server.MapPath(physicalFolderPath); if (!Directory.Exists(save_dir)) { Directory.CreateDirectory(save_dir); } physicalFullPath = physicalFolderPath + "/" + guid + Path.GetExtension(fileName); string savepath = Server.MapPath(physicalFullPath) ; hfc[0].SaveAs(savepath); isSuccess = true; msg = "上傳成功!"; } else { msg = "未識別任何有效文件!"; } } catch (Exception e) { msg = e.Message; } } return Json(new { state = isSuccess, message = msg,guid= guid, fileName = fileName, filePath = physicalFullPath }, JsonRequestBehavior.AllowGet); } catch { return Json(new { state = false, message = "上傳文件失敗!" }, JsonRequestBehavior.AllowGet); } }
附:dropzone經常使用配置項
url : 必要參數,文件的上傳地址; maxFiles : 默認爲null,能夠指定爲一個數值,限制最多文件數量。 maxFilesize : 限制文件的大小,單位是MB; acceptedFiles : 容許上傳的文件類型,文件擴展名以逗號隔開,格式見實例; autoProcessQueue : 默認爲true,即拖入文件當即自動上傳;若是須要在上傳以前有一些選擇的操做,而後手動上傳,能夠把該屬性設置爲false,而後手動點擊按鈕上傳; paramName : 至關於<input>元素的name屬性,默認爲file。 提示文本: dictDefaultMessage : 沒有任何文件被添加時的提示文本; dictFallbackMessage:Fallback 狀況下的提示文本。 dictInvalidInputType:文件類型被拒絕時的提示文本。 dictFileTooBig:文件大小過大時的提示文本。 dictCancelUpload:取消上傳連接的文本。 dictCancelUploadConfirmation:取消上傳確認信息的文本。 dictRemoveFile:移除文件連接的文本。 dictMaxFilesExceeded:超過最大文件數量的提示文本。
附:dropzone經常使用事件
addedfile : 添加文件是發生
removefile : 手動從服務器刪除文件時發生
success : 上傳成功後發生
complete:當文件上傳成功或失敗以後發生。
canceled:當文件在上傳時被取消的時候發生。
maxfilesreached:當文件數量達到最大時發生。
maxfilesexceeded:當文件數量超過限制時發生。
totaluploadprogress : 文件上傳中的返回值,第一個參數爲總上傳進度(0到100),第二個爲總字節數,第三個爲總上傳字節數,利用這幾個參數,可計算出上傳速度,和剩餘上傳時間;