uploadWithOthers.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. function uploadWithOthers(token, putExtra, config, domain) {
  2. controlTabDisplay("others");
  3. qiniu.getUploadUrl(config, token).then(function(res){
  4. var uploadUrl = res
  5. var board = {};
  6. var indexCount = 0;
  7. var resume = false;
  8. var chunk_size;
  9. var blockSize;
  10. var uploader = new plupload.Uploader({
  11. runtimes: "html5,flash,silverlight,html4",
  12. url: uploadUrl,
  13. browse_button: "select", // 触发文件选择对话框的按钮,为那个元素id
  14. flash_swf_url: "./js/Moxie.swf", // swf文件,当需要使用swf方式进行上传时需要配置该参数
  15. silverlight_xap_url: "./js/Moxie.xap",
  16. chunk_size: 4 * 1024 * 1024,
  17. max_retries: 3,
  18. multipart_params: {
  19. // token从服务端获取,没有token无法上传
  20. token: token
  21. },
  22. init: {
  23. PostInit: function() {
  24. console.log("upload init");
  25. },
  26. FilesAdded: function(up, files) {
  27. resume = false;
  28. $("#box input").attr("disabled", "disabled");
  29. $("#box button").css("backgroundColor", "#aaaaaa");
  30. chunk_size = uploader.getOption("chunk_size");
  31. var id = files[0].id;
  32. // 添加上传dom面板
  33. board[id] = addUploadBoard(files[0], config, files[0].name, "2");
  34. board[id].start = true;
  35. // 绑定上传按钮开始事件
  36. $(board[id])
  37. .find(".control-upload")
  38. .on("click", function() {
  39. if (board[id].start) {
  40. uploader.start();
  41. board[id].start = false;
  42. $(this).text("取消上传");
  43. } else {
  44. uploader.stop();
  45. board[id].start = true;
  46. $(this).text("开始上传");
  47. }
  48. });
  49. },
  50. FileUploaded: function(up, file, info) {
  51. console.log(info);
  52. },
  53. UploadComplete: function(up, files) {
  54. // Called when all files are either uploaded or failed
  55. console.log("[完成]");
  56. },
  57. Error: function(up, err) {
  58. console.log(err.response);
  59. }
  60. }
  61. });
  62. uploader.init();
  63. uploader.bind('Error',function(){
  64. console.log(1234)
  65. })
  66. uploader.bind("BeforeUpload", function(uploader, file) {
  67. key = file.name;
  68. putExtra.params["x:name"] = key.split(".")[0];
  69. var id = file.id;
  70. chunk_size = uploader.getOption("chunk_size");
  71. var directUpload = function() {
  72. var multipart_params_obj = {};
  73. multipart_params_obj.token = token;
  74. // filterParams 返回符合自定义变量格式的数组,每个值为也为一个数组,包含变量名及变量值
  75. var customVarList = qiniu.filterParams(putExtra.params);
  76. for (var i = 0; i < customVarList.length; i++) {
  77. var k = customVarList[i];
  78. multipart_params_obj[k[0]] = k[1];
  79. }
  80. multipart_params_obj.key = key;
  81. uploader.setOption({
  82. url: uploadUrl,
  83. multipart: true,
  84. multipart_params: multipart_params_obj
  85. });
  86. };
  87. var resumeUpload = function() {
  88. blockSize = chunk_size;
  89. initFileInfo(file);
  90. if(blockSize === 0){
  91. mkFileRequest(file)
  92. uploader.stop()
  93. return
  94. }
  95. resume = true;
  96. var multipart_params_obj = {};
  97. // 计算已上传的chunk数量
  98. var index = Math.floor(file.loaded / chunk_size);
  99. var dom_total = $(board[id])
  100. .find("#totalBar")
  101. .children("#totalBarColor");
  102. if (board[id].start != "reusme") {
  103. $(board[id])
  104. .find(".fragment-group")
  105. .addClass("hide");
  106. }
  107. dom_total.css(
  108. "width",
  109. file.percent + "%"
  110. );
  111. // 初始化已上传的chunk进度
  112. for (var i = 0; i < index; i++) {
  113. var dom_finished = $(board[id])
  114. .find(".fragment-group li")
  115. .eq(i)
  116. .find("#childBarColor");
  117. dom_finished.css("width", "100%");
  118. }
  119. var headers = qiniu.getHeadersForChunkUpload(token)
  120. uploader.setOption({
  121. url: uploadUrl + "/mkblk/" + blockSize,
  122. multipart: false,
  123. required_features: "chunks",
  124. headers: {
  125. Authorization: "UpToken " + token
  126. },
  127. multipart_params: multipart_params_obj
  128. });
  129. };
  130. // 判断是否采取分片上传
  131. if (
  132. (uploader.runtime === "html5" || uploader.runtime === "flash") &&
  133. chunk_size
  134. ) {
  135. if (file.size < chunk_size) {
  136. directUpload();
  137. } else {
  138. resumeUpload();
  139. }
  140. } else {
  141. console.log(
  142. "directUpload because file.size < chunk_size || is_android_weixin_or_qq()"
  143. );
  144. directUpload();
  145. }
  146. });
  147. uploader.bind("ChunkUploaded", function(up, file, info) {
  148. var res = JSON.parse(info.response);
  149. var leftSize = info.total - info.offset;
  150. var chunk_size = uploader.getOption && uploader.getOption("chunk_size");
  151. if (leftSize < chunk_size) {
  152. up.setOption({
  153. url: uploadUrl + "/mkblk/" + leftSize
  154. });
  155. }
  156. up.setOption({
  157. headers: {
  158. Authorization: "UpToken " + token
  159. }
  160. });
  161. // 更新本地存储状态
  162. var localFileInfo = JSON.parse(localStorage.getItem(file.name))|| [];
  163. localFileInfo[indexCount] = {
  164. ctx: res.ctx,
  165. time: new Date().getTime(),
  166. offset: info.offset,
  167. percent: file.percent
  168. };
  169. indexCount++;
  170. localStorage.setItem(file.name, JSON.stringify(localFileInfo));
  171. });
  172. // 每个事件监听函数都会传入一些很有用的参数,
  173. // 我们可以利用这些参数提供的信息来做比如更新UI,提示上传进度等操作
  174. uploader.bind("UploadProgress", function(uploader, file) {
  175. var id = file.id;
  176. // 更新进度条进度信息;
  177. var fileUploaded = file.loaded || 0;
  178. var dom_total = $(board[id])
  179. .find("#totalBar")
  180. .children("#totalBarColor");
  181. var percent = file.percent + "%";
  182. dom_total.css(
  183. "width",
  184. file.percent + "%"
  185. );
  186. $(board[id])
  187. .find(".speed")
  188. .text("进度:" + percent);
  189. var count = Math.ceil(file.size / uploader.getOption("chunk_size"));
  190. if (file.size > chunk_size) {
  191. updateChunkProgress(file, board[id], chunk_size, count);
  192. }
  193. });
  194. uploader.bind("FileUploaded", function(uploader, file, info) {
  195. var id = file.id;
  196. if (resume) {
  197. mkFileRequest(file)
  198. } else {
  199. uploadFinish(JSON.parse(info.response), file.name,board[id]);
  200. }
  201. });
  202. function updateChunkProgress(file, board, chunk_size, count) {
  203. var index = Math.ceil(file.loaded / chunk_size);
  204. var leftSize = file.loaded - chunk_size * (index - 1);
  205. if (index == count) {
  206. chunk_size = file.size - chunk_size * (index - 1);
  207. }
  208. var dom = $(board)
  209. .find(".fragment-group li")
  210. .eq(index - 1)
  211. .find("#childBarColor");
  212. dom.css(
  213. "width",
  214. leftSize / chunk_size *100 + "%"
  215. );
  216. }
  217. function uploadFinish(res, name, board) {
  218. localStorage.removeItem(name)
  219. $("#box input").removeAttr("disabled", "disabled");
  220. $("#box button").css("backgroundColor", "#00b7ee");
  221. $(board)
  222. .find("#totalBar")
  223. .addClass("hide");
  224. $(board)
  225. .find(".control-container")
  226. .html(
  227. "<p><strong>Hash:</strong>" +
  228. res.hash +
  229. "</p>" +
  230. "<p><strong>Bucket:</strong>" +
  231. res.bucket +
  232. "</p>"
  233. );
  234. if (res.key && res.key.match(/\.(jpg|jpeg|png|gif)$/)) {
  235. imageDeal(board, res.key, domain);
  236. }
  237. }
  238. function initFileInfo(file) {
  239. var localFileInfo = JSON.parse(localStorage.getItem(file.name))|| [];
  240. indexCount = 0;
  241. var length = localFileInfo.length
  242. if (length) {
  243. var clearStatus = false
  244. for (var i = 0; i < localFileInfo.length; i++) {
  245. indexCount++
  246. if (isExpired(localFileInfo[i].time)) {
  247. clearStatus = true
  248. localStorage.removeItem(file.name);
  249. break;
  250. }
  251. }
  252. if(clearStatus){
  253. indexCount = 0;
  254. return
  255. }
  256. file.loaded = localFileInfo[length - 1].offset;
  257. var leftSize = file.size - file.loaded;
  258. if(leftSize < chunk_size){
  259. blockSize = leftSize
  260. }
  261. file.percent = localFileInfo[length - 1].percent;
  262. return
  263. }else{
  264. indexCount = 0
  265. }
  266. }
  267. function mkFileRequest(file){
  268. // 调用sdk的url构建函数
  269. var requestUrl = qiniu.createMkFileUrl(
  270. uploadUrl,
  271. file.size,
  272. key,
  273. putExtra
  274. );
  275. var ctx = []
  276. var id = file.id
  277. var local = JSON.parse(localStorage.getItem(file.name))
  278. for(var i =0;i<local.length;i++){
  279. ctx.push(local[i].ctx)
  280. }
  281. // 设置上传的header信息
  282. var headers = qiniu.getHeadersForMkFile(token)
  283. $.ajax({url: requestUrl, type: "POST", headers: headers, data: ctx.join(","), success: function(res){
  284. uploadFinish(res, file.name,board[id]);
  285. }})
  286. }
  287. function isExpired(time){
  288. let expireAt = time + 3600 * 24* 1000;
  289. return new Date().getTime() > expireAt;
  290. }
  291. });
  292. }