利用WebUploader實現大檔案上傳和視訊上傳
檔案上傳是網站開發必不可少的,常見的有圖片上傳。但是大檔案和視訊上傳不常見。這裡我將自己寫的視訊上傳demo貼出來供大家參考:
利用是最新的WebUploader外掛請 下載使用最新版即可
js程式碼
_extensions ='3gp,mp4,rmvb,mov,avi,m4v'; _mimeTypes ='video/*,audio/*,application/*'; $(function(){ var chunkSize = 500 * 1024; //分塊大小 var uniqueFileName = null; //檔案唯一識別符號 var md5Mark = null; // var _backEndUrl = ''; WebUploader.Uploader.register({ "before-send-file": "beforeSendFile" , "before-send": "beforeSend" , "after-send-file": "afterSendFile" }, { beforeSendFile: function(file){ console.log(file); //秒傳驗證 var task = new $.Deferred(); var start = new Date().getTime(); (new WebUploader.Uploader()).md5File(file, 0, 10*1024*1024).progress(function(percentage){ }).then(function(val){ md5Mark = val; _userInfo.md5 = val; $.ajax({ type: "POST", url: _backEndUrl, data: { status: "md5Check", md5: val }, cache: false, timeout: 1000, //todo 超時的話,只能認為該檔案不曾上傳過 dataType: "json" }).then(function(data, textStatus, jqXHR){ if(data.ifExist){ //若存在,這返回失敗給WebUploader,表明該檔案不需要上傳 task.reject(); uploader.skipFile(file); file.path = data.path; UploadComlate(file); }else{ task.resolve(); //拿到上傳檔案的唯一名稱,用於斷點續傳 uniqueFileName = md5(_userInfo.openid+_userInfo.time); } }, function(jqXHR, textStatus, errorThrown){ //任何形式的驗證失敗,都觸發重新上傳 task.resolve(); //拿到上傳檔案的唯一名稱,用於斷點續傳 uniqueFileName = md5(_userInfo.openid+_userInfo.time); }); }); return $.when(task); } , beforeSend: function(block){ //分片驗證是否已傳過,用於斷點續傳 var task = new $.Deferred(); $.ajax({ type: "POST" , url: _backEndUrl , data: { status: "chunkCheck" , name: uniqueFileName , chunkIndex: block.chunk , size: block.end - block.start } , cache: false , timeout: 1000 //todo 超時的話,只能認為該分片未上傳過 , dataType: "json" }).then(function(data, textStatus, jqXHR){ if(data.ifExist){ //若存在,返回失敗給WebUploader,表明該分塊不需要上傳 task.reject(); }else{ task.resolve(); } }, function(jqXHR, textStatus, errorThrown){ //任何形式的驗證失敗,都觸發重新上傳 task.resolve(); }); return $.when(task); } , afterSendFile: function(file){ var chunksTotal = 0; if((chunksTotal = Math.ceil(file.size/chunkSize)) > 1){ //合併請求 var task = new $.Deferred(); $.ajax({ type: "POST" , url: _backEndUrl , data: { status: "chunksMerge" , name: uniqueFileName , chunks: chunksTotal , ext: file.ext , md5: md5Mark } , cache: false , dataType: "json" }).then(function(data, textStatus, jqXHR){ //todo 檢查響應是否正常 task.resolve(); file.path = data.path; UploadComlate(file); }, function(jqXHR, textStatus, errorThrown){ task.reject(); }); return $.when(task); }else{ UploadComlate(file); } } }); var uploader = WebUploader.create({ swf: "./Uploader.swf", server: _backEndUrl, //伺服器處理檔案的路徑 pick: "#picker", //指定選擇檔案的按鈕,此處放的是id resize: false, dnd: "#theList", //上傳檔案的拖拽容器(即,如果選擇用拖拽的方式選擇檔案進行上傳,應該要把檔案拖拽到的區域容器) paste: document.body, //[可選] [預設值:undefined]指定監聽paste事件的容器,如果不指定,不啟用此功能。此功能為通過貼上來新增截圖的圖片。建議設定為document.body disableGlobalDnd: true, //[可選] [預設值:false]是否禁掉整個頁面的拖拽功能,如果不禁用,圖片拖進來的時候會預設被瀏覽器開啟。 compress: false, prepareNextFile: true, chunked: true, chunkSize: chunkSize, chunkRetry: 2, //[可選] [預設值:2]如果某個分片由於網路問題出錯,允許自動重傳多少次? threads: true, //[可選] [預設值:3] 上傳併發數。允許同時最大上傳程序數。 formData: function(){return $.extend(true, {}, _userInfo);}, fileNumLimit: 1, fileSingleSizeLimit: 50 * 1024 * 1024,// 限制在50M duplicate: true, accept: { title: '大檔案上傳', //文字描述 extensions: _extensions, //允許的檔案字尾,不帶點,多個用逗號分割。,jpg,png, mimeTypes: _mimeTypes, //多個用逗號分割。image/*, }, }); /** * 驗證檔案格式以及檔案大小 */ uploader.on("error",function (type,handler){ if (type=="Q_TYPE_DENIED"){ swal({ title:'', text: '請上傳MP4格式的視訊~', type: "warning", confirmButtonColor: "#DD6B55", confirmButtonText: "我知道了", }); }else if(type=="F_EXCEED_SIZE"){ swal({ title:'', text: '視訊大小不能超過50M哦~', type: "warning", confirmButtonColor: "#DD6B55", confirmButtonText: "我知道了", }); } }); uploader.on("fileQueued", function(file){ $('#theList').show(); $("#theList").append('<li id="'+file.id+'" class="upload_li">' + ' <img /> <span class="file_name upload_li">'+file.name+'</span></li><li class="upload_li"><span class="itemUpload weui-btn weui-btn_mini weui-btn_primary">上傳</span><span class="itemStop weui-btn weui-btn_mini weui-btn_default">暫停</span><span class="itemDel weui-btn weui-btn_mini weui-btn_warn">刪除</span></li><li class="upload_li">' + '<div id="percentage'+file.id+'" class="percentage"><div class="weui-progress__bar"><div class="weui-progress__inner-bar js_progress" style="width: 0%;"></div> <b id="pers"></b> </div></div>' + '</li>'); var $img = $("#" + file.id).find("img"); uploader.makeThumb(file, function(error, src){ if(error){ $img.replaceWith("<span class='no_view'>視訊暫不能預覽</span>"); } $img.attr("src", src); }); }); $("#theList").on("click", ".itemUpload", function(){ uploader.upload(); //"上傳"-->"暫停" $(this).hide(); $(".itemStop").css('display','inline-block'); $(".itemStop").show(); }); $("#theList").on("click", ".itemStop", function(){ uploader.stop(true); //"暫停"-->"上傳" $(this).hide(); $(".itemUpload").show(); }); //todo 如果要刪除的檔案正在上傳(包括暫停),則需要傳送給後端一個請求用來清除伺服器端的快取檔案 $("#theList").on("click", ".itemDel", function(){ uploader.removeFile($('.upload_li').attr("id")); //從上傳檔案列表中刪除 $('.upload_li').remove(); //從上傳列表dom中刪除 }); uploader.on("uploadProgress", function(file, percentage){ $(".percentage").find('.js_progress').css("width",percentage * 100 + "%"); $(".percentage").find('#pers').text(parseInt(percentage * 100) + "%"); }); function UploadComlate(file){ console.log(file); if(file && file.name){ $('#vedio').val(file.name); $(".percentage").find('#pers').html("<span style='color:green;'>上傳完畢</span>"); $(".itemStop").hide(); $(".itemUpload").hide(); $(".itemDel").hide(); }else{ $(".percentage").find('#pers').html("<span style='color:red;'>上傳失敗,請您檢查網路狀況~</span>"); $(".itemStop").hide(); $(".itemUpload").hide(); } } })
PHP控制器
public function vupload(){ set_time_limit (0); //關閉快取 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); $ip_path = './uploads/'.$_SESSION['userinfo']['id']; $save_path = 'uploads/'.$_SESSION['userinfo']['id']; $uploader = new \Org\Util\Vupload; $uploader->set('path',$ip_path); //用於斷點續傳,驗證指定分塊是否已經存在,避免重複上傳 if(isset($_POST['status'])){ if($_POST['status'] == 'chunkCheck'){ $target = $ip_path.'/'.$_POST['name'].'/'.$_POST['chunkIndex']; if(file_exists($target) && filesize($target) == $_POST['size']){ die('{"ifExist":1}'); } die('{"ifExist":0}'); }elseif($_POST['status'] == 'md5Check'){ //todo 模擬持久層查詢 $dataArr = array( 'b0201e4d41b2eeefc7d3d355a44c6f5a' => 'kazaff2.jpg' ); if(isset($dataArr[$_POST['md5']])){ die('{"ifExist":1, "path":"'.$dataArr[$_POST['md5']].'"}'); } die('{"ifExist":0}'); }elseif($_POST['status'] == 'chunksMerge'){ if($path = $uploader->chunksMerge($_POST['name'], $_POST['chunks'], $_POST['ext'])){ //todo 把md5簽名存入持久層,供未來的秒傳驗證 session('video_path', $save_path.'/'.$path); die('{"status":1, "path": "'.$save_path.'/'.$path.'"}'); } die('{"status":0}'); } } if(($path = $uploader->upload('file', $_POST)) !== false){ if(!session('video_path')){ session('video_path', $save_path.'/'.$path); } die('{"status":1, "path": "'.$save_path.'/'.$path.'"}'); } die('{"status":0}'); }
封裝的上傳類庫
<?php
/**
*
* 版權所有:重慶市環境保護資訊中心
* 作 者:Sqc
* 日 期:2016-12-06
* 版 本:1.0.0
* 功能說明:用於視訊等上傳。
*
**/
namespace Org\Util;
Class Vupload
{
//要配置的內容
private $path = "./uploads";
private $allowtype = array('jpg', 'gif', 'png', 'mp4', 'mp3','3gp','rmvb','mov','avi','m4v');
private $maxsize = 104857600;//
private $israndname = true;
private $originName;
private $tmpFileName;
private $fileType;
private $fileSize;
private $newFileName;
private $errorNum = 0;
private $errorMess = "";
private $isChunk = false;
private $indexOfChunk = 0;
public function _initialize(){
parent::_initialize();
}
/**
* 用於設定成員屬性($path, $allowtype, $maxsize, $israndname)
* 可以通過連貫操作一次設定多個屬性值
* @param $key 成員屬性(不區分大小寫)
* @param $val 為成員屬性設定的值
* @return object 返回自己物件$this, 可以用於連貫操作
*/
function set($key, $val){
$key = strtolower($key);
if (array_key_exists($key, get_class_vars(get_class($this)))){
$this->setOption($key, $val);
}
return $this;
}
/**
* 呼叫該方法上傳檔案
* Enter description here ...
* @param $fileField 上傳檔案的表單名稱
*
*/
function upload($fileField, $info){
//判斷是否為分塊上傳
$this->checkChunk($info);
if (!$this->checkFilePath($this->path)){
$this->errorMess = $this->getError();
return false;
}
//將檔案上傳的資訊取出賦給變數
$name = $_FILES[$fileField]['name'];
$tmp_name = $_FILES[$fileField]['tmp_name'];
$size = $_FILES[$fileField]['size'];
$error = $_FILES[$fileField]['error'];
//設定檔案資訊
if ($this->setFiles($name, $tmp_name, $size, $error)){
//如果是分塊,則建立一個唯一名稱的資料夾用來儲存該檔案的所有分塊
if($this->isChunk){
$uploadDir = $this->path;
if($info){
$tmpName = $this->setDirNameForChunks();
if(!$this->checkFilePath($uploadDir . '/' . $tmpName)){
$this->errorMess = $this->getError();
return false;
}
}
// $tmpName = $this->setDirNameForChunks($info);
// if(!$this->checkFilePath($uploadDir . '/' . $tmpName)){
// $this->errorMess = $this->getError();
// return false;
// }
//建立一個對應的檔案,用來記錄上傳分塊檔案的修改時間,用於清理長期未完成的垃圾分塊
touch($uploadDir.'/'.$tmpName.'.tmp');
}
if($this->checkFileSize() && $this->checkFileType()){
$this->setNewFileName();
if ($this->copyFile()){
return $this->newFileName;
}
}
}
$this->errorMess = $this->getError();
return false;
}
public function chunksMerge($uniqueFileName, $chunksTotal, $fileExt){
$targetDir = $this->path.'/'.$uniqueFileName;
//檢查對應資料夾中的分塊檔案數量是否和總數保持一致
if($chunksTotal > 1 && (count(scandir($targetDir)) - 2) == $chunksTotal){
//同步鎖機制
$lockFd = fopen($this->path.'/'.$uniqueFileName.'.lock', "w");
if(!flock($lockFd, LOCK_EX | LOCK_NB)){
fclose($lockFd);
return false;
}
//進行合併
$this->fileType = $fileExt;
$finalName = $this->path.'/'.($this->setOption('newFileName', $this->proRandName()));
$file = fopen($finalName, 'wb');
for($index = 0; $index < $chunksTotal; $index++){
$tmpFile = $targetDir.'/'.$index;
$chunkFile = fopen($tmpFile, 'rb');
$content = fread($chunkFile, filesize($tmpFile));
fclose($chunkFile);
fwrite($file, $content);
//刪除chunk檔案
unlink($tmpFile);
}
fclose($file);
//刪除chunk資料夾
rmdir($targetDir);
unlink($this->path.'/'.$uniqueFileName.'.tmp');
//解鎖
flock($lockFd, LOCK_UN);
fclose($lockFd);
unlink($this->path.'/'.$uniqueFileName.'.lock');
return $this->newFileName;
}
return false;
}
//獲取上傳後的檔名稱
public function getFileName(){
return $this->newFileName;
}
//上傳失敗後,呼叫該方法則返回,上傳出錯資訊
public function getErrorMsg(){
return $this->errorMess;
}
//設定上傳出錯資訊
public function getError(){
$str = "上傳檔案<font color='red'>{$this->originName}</font>時出錯:";
switch ($this->errorNum) {
case 4:
$str.= "沒有檔案被上傳";
break;
case 3:
$str.= "檔案只有部分被上傳";
break;
case 2:
$str.= "上傳檔案的大小超過了HTML表單中MAX_FILE_SIZE選項指定的值";
break;
case 1:
$str.= "上傳的檔案超過了php.ini中upload_max_filesize選項限制的值";
break;
case -1:
$str.= "未允許的型別";
break;
case -2:
$str.= "檔案過大, 上傳的資料夾不能超過{$this->maxsize}個位元組";
break;
case -3:
$str.= "上傳失敗";
break;
case -4:
$str.= "建立存放上傳檔案目錄失敗,請重新指定上傳目錄";
break;
case -5:
$str.= "必須指定上傳檔案的路徑";
break;
default:
$str .= "未知錯誤";
}
return $str."<br>";
}
//根據檔案的相關資訊為分塊資料建立資料夾
//md5(當前登入使用者的資料庫id + 檔案原始名稱 + 檔案型別 + 檔案最後修改時間 + 檔案總大小)
private function setDirNameForChunks(){
$str = $_SESSION['userinfo']['openid'].$_SESSION['userinfo']['report_time'];
return md5($str);
return $str;
}
//設定和$_FILES有關的內容
private function setFiles($name="", $tmp_name="", $size=0, $error=0){
$this->setOption('errorNum', $error);
if ($error) {
return false;
}
$this->setOption('originName', $name);
$this->setOption('tmpFileName', $tmp_name);
$aryStr = explode(".", $name);
$this->setOption("fileType", strtolower($aryStr[count($aryStr)-1]));
$this->setOption("fileSize", $size);
return true;
}
private function checkChunk($info){
if(isset($info['chunks']) && $info['chunks'] > 0){
$this->setOption("isChunk", true);
if(isset($info['chunk']) && $info['chunk'] >= 0){
$this->setOption("indexOfChunk", $info['chunk']);
return true;
}
throw new Exception('分塊索引不合法');
}
return false;
}
//為單個成員屬性設定值
private function setOption($key, $val){
$this->$key = $val;
return $val;
}
//設定上傳後的檔名稱
private function setNewFileName(){
if($this->isChunk){ //如果是分塊,則以分塊的索引作為檔名稱儲存
$this->setOption('newFileName', $this->indexOfChunk);
}elseif($this->israndname) {
$this->setOption('newFileName', $this->proRandName());
}else{
$this->setOption('newFileName', $this->originName);
}
}
//檢查上傳的檔案是否是合法的型別
private function checkFileType(){
if (in_array(strtolower($this->fileType), $this->allowtype)) {
return true;
}else{
$this->setOption('errorNum', -1);
return false;
}
}
//檢查上傳的檔案是否是允許的大小
private function checkFileSize(){
if ($this->fileSize > $this->maxsize) {
$this->setOption('errorNum', -5);
return false;
}else{
return true;
}
}
//檢查是否有存放上傳檔案的目錄
private function checkFilePath($target){
if (empty($target)) {
$this->setOption('errorNum', -5);
return false;
}
if (!file_exists($target) || !is_writable($target)) {
if ( [email protected]($target, 0755)) {
$this->setOption('errorNum', -4);
return false;
}
}
$this->path = $target;
return true;
}
//設定隨機檔名
private function proRandName(){
$fileName = date('YmdHis')."_".rand(100,999);
return $fileName.'.'.$this->fileType;
}
//複製上傳檔案到指定的位置
private function copyFile(){
if (!$this->errorNum) {
$path = rtrim($this->path, '/').'/';
$path.= $this->newFileName;
if (@move_uploaded_file($this->tmpFileName, $path)) {
return true;
}else{
$this->setOption('errorNum', -3);
return false;
}
}else{
return false;
}
}
}
相關推薦
利用WebUploader實現大檔案上傳和視訊上傳
檔案上傳是網站開發必不可少的,常見的有圖片上傳。但是大檔案和視訊上傳不常見。這裡我將自己寫的視訊上傳demo貼出來供大家參考: 利用是最新的WebUploader外掛請 下載使用最新版即可 js程式碼 _extensions ='3gp,mp4,rmvb,mov,avi,
springboot 整合 gridfs 、webUploader實現大檔案分塊上傳、斷點續傳、秒傳
主要的pom.xml: <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId>
webuploader實現大檔案上傳
目前在公司專案裡遇到了需要上傳大檔案(視訊、音訊)的情況,特此記錄。 此次專案引用了一款名為Webuploader的外掛。官網:http://fex.baidu.com/webuploader/getting-started.html html程式碼: <html
使用百度webuploader實現大檔案上傳
寫在前面 後臺的上傳檔案,都是50M左右比較小,後面說需要上傳大一點500M以上的,一直沒整過這方面的,昨天在網上看下其他人的實現方式,東看看西借鑑之後就有了下面的東西 第一部分 頁面 頁面實現了簡單的分片上傳檔案
WebUploader 實現大檔案的斷點續傳功能
斷點續傳指的是在下載或上傳時,將下載或上傳任務(一個檔案或一個壓縮包)人為的劃分為幾個部分,每一個部分採用一個片段進行上傳或下載,如果碰到網路故障,可以從已經上傳或下載的部分開始繼續上傳下載未完成的部分,而沒有必要從頭開始上傳下載。使用者可以節省
利用Python實現csv檔案的合併和去重
方法一: 這種方法需要引入glob模組 glob模組是最簡單的模組之一,內容非常少。用它可以查詢符合特定規則的檔案路徑名。跟使用windows下的檔案搜尋差不多。查詢檔案只用到三個匹配符:”*”, “?”, “[]”。”*”匹配0個或多個字元;”?”匹配單個字元;”[]”匹配指定範圍內的
利用JavaScript實現音訊檔案的播放和暫停
HTML5 規定了一種通過 audio 元素來包含音訊的標準方法。 audio 元素能夠播放聲音檔案或者音訊流。 注意看,a.paused表示當前音訊的狀態,而音訊的暫停和播放對應的方法分別為pause()和play() ——-(自認為很值得注意的地方 我
利用nodejs進行大檔案(比如線上視訊)的讀取
nodejs進行視訊讀取時不能像讀取圖片之類的一次性讀取,而是必須讀取一部分返回一部分,這樣客戶端的播放才會邊緩衝邊播放,而不必等待全部緩衝完再播放。 老規矩,直接貼程式碼講解: <span style="white-space:pre"> </span
C#實現大檔案上傳功能(二)---webuploader上傳
一、問題來源 近些時候,處理專案的時候發現如果使用者上傳大檔案的時候使用HtmlInputFile通過httppostfilebase 來實現上傳,如果檔案較小的話較小的話,上傳沒有問題(4M)
webuploader實現多檔案上傳
問題: 1: 上傳失敗,不知道怎麼在服務端寫返回值? 2: 做個多檔案上傳怎麼辦? 1:上傳失敗,不知道怎麼在服務端寫返回值? (1):首先在初始化Web Uploader 的方法寫上 server: 'http://localho
網頁內實現大檔案分片上傳、斷點續傳
最近做公司的專案,需要在後臺控制系統中新增一個功能-------向伺服器傳送程式更新包;這些程式更新包大小不固定,但基本都在1G到4G之間,剛開始還真是難倒我了,因為之前的專案中沒有上傳過這麼大的檔案,還要斷點續傳,後來經過查資料,寫DEMO,這個問題終於解決了; 解決辦法: 使用XMLHt
在Selenium 利用AutoIt實現圖片檔案上傳
1. AutoIT安裝 下載並安裝AutoIT,下載連結:https://www.autoitscript.com/site/autoit/ AutoIT安裝成功後,可以在開始選單下看到AutoIT的所有工具,如下圖所示: 其中分為幾類,AutoIT
【前端】利用ajax實現偽檔案非同步上傳下載
利用ajax可以實現很酷的效果,在不重新整理頁面的情況下提交表單、修改資料狀態等等,可是如果表單裡還有input:file可就慘了,ajax不支援檔案的處理啊! ajax是使用了瀏覽器內部的XmlHttpRequest物件來傳輸XML資料的。既然是Xml的資料傳輸,那麼傳輸
java實現大檔案上傳
檔案上傳是最古老的網際網路操作之一,20多年來幾乎沒有怎麼變化,還是操作麻煩、缺乏互動、使用者體驗差。 一、前端程式碼 英國程式設計師Remy Sharp總結了這些新的介面 ,本文在他的基礎之上,討論在前端採用HTML5的API,對檔案上傳進行漸進式增強: * iframe上傳 *
檔案的上傳和下載—上傳的實現,注意事項
實現WEB開發中的檔案上傳功能,需完成如下二步操作: 在WEB頁面中新增上傳輸入項,<input type=“life” name=“”>,使用時注意: 1. 必須要設定input輸入項的name屬性,否則瀏覽器將不會發送上傳檔案的資料。 2. 必須把i
php 上傳大檔案——配置upload_max_filesize和post_max_size
本地php環境一般是phpstudy或wamp等整合環境,都能找到php.ini檔案。 php.ini配置檔案中預設檔案上傳大小是2M,即upload_max_filesize = 2M.如果超過則會
使用原生Java Web來實現大檔案的上傳
BigFileUpload 目錄 背景介紹 專案介紹 使用說明 獲取程式碼 需要知識點 啟動專案 專案示範 核心講解 功能分析 分塊上傳 秒傳功能 斷點續傳 總結 背景介紹 這個專案是在朋友的一次面試中,面試人提出了一個問題.
實現大檔案上傳的辦法
方法一: 對ini進行修改file_uploads = on;//是否允許通過http上傳檔案的開關(預設為開) upload_max_filesize = 8m // php允許最大上傳檔案大小 post_max_size = 8m;//表單post提交允許最大上傳檔案大
iOS大檔案分片上傳和斷點續傳
總結一下大檔案分片上傳和斷點續傳的問題。因為檔案過大(比如1G以上),必須要考慮上傳過程網路中斷的情況。http的網路請求中本身就已經具備了分片上傳功能,當傳輸的檔案比較大時,http協議自動會將檔案切片(分塊),但這不是我們現在說的重點,我們要做的事是保證在網路中斷後1G
java實現大檔案的上傳
最近專案經理逼著讓偶做樹的展開,表巢狀表,可惜偶剛參加工作,水平低,這不在查資料嘛,可是不多久就傳來了經理的叫囂聲,這麼簡單的東西,都一天了,你還沒做完..................,哎真是鬱悶,誰讓咱水平低呢(心想,什麼時候等我水平提高了,看我怎麼收拾你,又一想,等