github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/qiniu-js-sdk-master/demo/js/qiniu.js (about)

     1  /*global plupload ,mOxie*/
     2  /*global ActiveXObject */
     3  /*exported Qiniu */
     4  
     5  function QiniuJsSDK() {
     6  
     7  
     8      this.detectIEVersion = function() {
     9          var v = 4,
    10              div = document.createElement('div'),
    11              all = div.getElementsByTagName('i');
    12          while (
    13              div.innerHTML = '<!--[if gt IE ' + v + ']><i></i><![endif]-->',
    14              all[0]
    15          ) {
    16              v++;
    17          }
    18          return v > 4 ? v : false;
    19      };
    20  
    21      this.isImage = function(url) {
    22          var res, suffix = "";
    23          var imageSuffixes = ["png", "jpg", "jpeg", "gif", "bmp"];
    24          var suffixMatch = /\.([a-zA-Z0-9]+)(\?|\@|$)/;
    25  
    26          if (!url || !suffixMatch.test(url)) {
    27              return false;
    28          }
    29          res = suffixMatch.exec(url);
    30          suffix = res[1].toLowerCase();
    31          for (var i = 0, l = imageSuffixes.length; i < l; i++) {
    32              if (suffix === imageSuffixes[i]) {
    33                  return true;
    34              }
    35          }
    36          return false;
    37      };
    38  
    39      this.getFileExtension = function(filename) {
    40          var tempArr = filename.split(".");
    41          var ext;
    42          if (tempArr.length === 1 || (tempArr[0] === "" && tempArr.length === 2)) {
    43              ext = "";
    44          } else {
    45              ext = tempArr.pop().toLowerCase(); //get the extension and make it lower-case
    46          }
    47          return ext;
    48      };
    49  
    50      this.utf8_encode = function(argString) {
    51          // http://kevin.vanzonneveld.net
    52          // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    53          // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    54          // +   improved by: sowberry
    55          // +    tweaked by: Jack
    56          // +   bugfixed by: Onno Marsman
    57          // +   improved by: Yves Sucaet
    58          // +   bugfixed by: Onno Marsman
    59          // +   bugfixed by: Ulrich
    60          // +   bugfixed by: Rafal Kukawski
    61          // +   improved by: kirilloid
    62          // +   bugfixed by: kirilloid
    63          // *     example 1: this.utf8_encode('Kevin van Zonneveld');
    64          // *     returns 1: 'Kevin van Zonneveld'
    65  
    66          if (argString === null || typeof argString === 'undefined') {
    67              return '';
    68          }
    69  
    70          var string = (argString + ''); // .replace(/\r\n/g, '\n').replace(/\r/g, '\n');
    71          var utftext = '',
    72              start, end, stringl = 0;
    73  
    74          start = end = 0;
    75          stringl = string.length;
    76          for (var n = 0; n < stringl; n++) {
    77              var c1 = string.charCodeAt(n);
    78              var enc = null;
    79  
    80              if (c1 < 128) {
    81                  end++;
    82              } else if (c1 > 127 && c1 < 2048) {
    83                  enc = String.fromCharCode(
    84                      (c1 >> 6) | 192, (c1 & 63) | 128
    85                  );
    86              } else if (c1 & 0xF800 ^ 0xD800 > 0) {
    87                  enc = String.fromCharCode(
    88                      (c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
    89                  );
    90              } else { // surrogate pairs
    91                  if (c1 & 0xFC00 ^ 0xD800 > 0) {
    92                      throw new RangeError('Unmatched trail surrogate at ' + n);
    93                  }
    94                  var c2 = string.charCodeAt(++n);
    95                  if (c2 & 0xFC00 ^ 0xDC00 > 0) {
    96                      throw new RangeError('Unmatched lead surrogate at ' + (n - 1));
    97                  }
    98                  c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
    99                  enc = String.fromCharCode(
   100                      (c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
   101                  );
   102              }
   103              if (enc !== null) {
   104                  if (end > start) {
   105                      utftext += string.slice(start, end);
   106                  }
   107                  utftext += enc;
   108                  start = end = n + 1;
   109              }
   110          }
   111  
   112          if (end > start) {
   113              utftext += string.slice(start, stringl);
   114          }
   115  
   116          return utftext;
   117      };
   118  
   119      this.base64_encode = function(data) {
   120          // http://kevin.vanzonneveld.net
   121          // +   original by: Tyler Akins (http://rumkin.com)
   122          // +   improved by: Bayron Guevara
   123          // +   improved by: Thunder.m
   124          // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
   125          // +   bugfixed by: Pellentesque Malesuada
   126          // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
   127          // -    depends on: this.utf8_encode
   128          // *     example 1: this.base64_encode('Kevin van Zonneveld');
   129          // *     returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
   130          // mozilla has this native
   131          // - but breaks in 2.0.0.12!
   132          //if (typeof this.window['atob'] == 'function') {
   133          //    return atob(data);
   134          //}
   135          var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
   136          var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
   137              ac = 0,
   138              enc = '',
   139              tmp_arr = [];
   140  
   141          if (!data) {
   142              return data;
   143          }
   144  
   145          data = this.utf8_encode(data + '');
   146  
   147          do { // pack three octets into four hexets
   148              o1 = data.charCodeAt(i++);
   149              o2 = data.charCodeAt(i++);
   150              o3 = data.charCodeAt(i++);
   151  
   152              bits = o1 << 16 | o2 << 8 | o3;
   153  
   154              h1 = bits >> 18 & 0x3f;
   155              h2 = bits >> 12 & 0x3f;
   156              h3 = bits >> 6 & 0x3f;
   157              h4 = bits & 0x3f;
   158  
   159              // use hexets to index into b64, and append result to encoded string
   160              tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
   161          } while (i < data.length);
   162  
   163          enc = tmp_arr.join('');
   164  
   165          switch (data.length % 3) {
   166              case 1:
   167                  enc = enc.slice(0, -2) + '==';
   168                  break;
   169              case 2:
   170                  enc = enc.slice(0, -1) + '=';
   171                  break;
   172          }
   173  
   174          return enc;
   175      };
   176  
   177      this.URLSafeBase64Encode = function(v) {
   178          v = this.base64_encode(v);
   179          return v.replace(/\//g, '_').replace(/\+/g, '-');
   180      };
   181  
   182      this.createAjax = function(argument) {
   183          var xmlhttp = {};
   184          if (window.XMLHttpRequest) {
   185              xmlhttp = new XMLHttpRequest();
   186          } else {
   187              xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
   188          }
   189          return xmlhttp;
   190      };
   191  
   192      this.parseJSON = function(data) {
   193          // Attempt to parse using the native JSON parser first
   194          if (window.JSON && window.JSON.parse) {
   195              return window.JSON.parse(data);
   196          }
   197  
   198          if (data === null) {
   199              return data;
   200          }
   201          if (typeof data === "string") {
   202  
   203              // Make sure leading/trailing whitespace is removed (IE can't handle it)
   204              data = this.trim(data);
   205  
   206              if (data) {
   207                  // Make sure the incoming data is actual JSON
   208                  // Logic borrowed from http://json.org/json2.js
   209                  if (/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, "@").replace(/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
   210  
   211                      return (function() {
   212                          return data;
   213                      })();
   214                  }
   215              }
   216          }
   217      };
   218  
   219      this.trim = function(text) {
   220          return text === null ? "" : this.trim.call(text);
   221      };
   222  
   223      //Todo ie7 handler / this.parseJSON bug;
   224  
   225      var that = this;
   226  
   227      this.uploader = function(op) {
   228          if (!op.domain) {
   229              throw 'uptoken_url or domain is required!';
   230          }
   231  
   232          if (!op.browse_button) {
   233              throw 'browse_button is required!';
   234          }
   235  
   236          var option = {};
   237  
   238          var _Error_Handler = op.init && op.init.Error;
   239          var _FileUploaded_Handler = op.init && op.init.FileUploaded;
   240  
   241          op.init.Error = function() {};
   242          op.init.FileUploaded = function() {};
   243  
   244          that.uptoken_url = op.uptoken_url;
   245          that.token = '';
   246          that.key_handler = typeof op.init.Key === 'function' ? op.init.Key : '';
   247          this.domain = op.domain;
   248          var ctx = '';
   249          var speedCalInfo = {
   250              isResumeUpload: false,
   251              resumeFilesize: 0,
   252              startTime: '',
   253              currentTime: ''
   254          };
   255  
   256          var reset_chunk_size = function() {
   257              var ie = that.detectIEVersion();
   258              var BLOCK_BITS, MAX_CHUNK_SIZE, chunk_size;
   259              var isSpecialSafari = (mOxie.Env.browser === "Safari" && mOxie.Env.version <= 5 && mOxie.Env.os === "Windows" && mOxie.Env.osVersion === "7") || (mOxie.Env.browser === "Safari" && mOxie.Env.os === "iOS" && mOxie.Env.osVersion === "7");
   260              if (ie && ie <= 9 && op.chunk_size && op.runtimes.indexOf('flash') >= 0) {
   261                  //  link: http://www.plupload.com/docs/Frequently-Asked-Questions#when-to-use-chunking-and-when-not
   262                  //  when plupload chunk_size setting is't null ,it cause bug in ie8/9  which runs  flash runtimes (not support html5) .
   263                  op.chunk_size = 0;
   264  
   265              } else if (isSpecialSafari) {
   266                  // win7 safari / iOS7 safari have bug when in chunk upload mode
   267                  // reset chunk_size to 0
   268                  // disable chunk in special version safari
   269                  op.chunk_size = 0;
   270              } else {
   271                  BLOCK_BITS = 20;
   272                  MAX_CHUNK_SIZE = 4 << BLOCK_BITS; //4M
   273  
   274                  chunk_size = plupload.parseSize(op.chunk_size);
   275                  if (chunk_size > MAX_CHUNK_SIZE) {
   276                      op.chunk_size = MAX_CHUNK_SIZE;
   277                  }
   278                  // qiniu service  max_chunk_size is 4m
   279                  // reset chunk_size to max_chunk_size(4m) when chunk_size > 4m
   280              }
   281          };
   282          reset_chunk_size();
   283  
   284          var getUpToken = function() {
   285              if (!op.uptoken) {
   286                  var ajax = that.createAjax();
   287                  ajax.open('GET', that.uptoken_url, true);
   288                  ajax.setRequestHeader("If-Modified-Since", "0");
   289                  ajax.onreadystatechange = function() {
   290                      if (ajax.readyState === 4 && ajax.status === 200) {
   291                          var res = that.parseJSON(ajax.responseText);
   292                          that.token = res.uptoken;
   293                      }
   294                  };
   295                  ajax.send();
   296              } else {
   297                  that.token = op.uptoken;
   298              }
   299          };
   300  
   301          var getFileKey = function(up, file, func) {
   302              var key = '',
   303                  unique_names = false;
   304              if (!op.save_key) {
   305                  unique_names = up.getOption && up.getOption('unique_names');
   306                  unique_names = unique_names || (up.settings && up.settings.unique_names);
   307                  if (unique_names) {
   308                      var ext = that.getFileExtension(file.name);
   309                      key = ext ? file.id + '.' + ext : file.id;
   310                  } else if (typeof func === 'function') {
   311                      key = func(up, file);
   312                  } else {
   313                      key = file.name;
   314                  }
   315              }
   316              return key;
   317          };
   318  
   319          plupload.extend(option, op, {
   320              url: 'http://upload.qiniu.com',
   321              multipart_params: {
   322                  token: ''
   323              }
   324          });
   325  
   326          var uploader = new plupload.Uploader(option);
   327  
   328          uploader.bind('Init', function(up, params) {
   329              getUpToken();
   330          });
   331          uploader.init();
   332  
   333          uploader.bind('FilesAdded', function(up, files) {
   334              var auto_start = up.getOption && up.getOption('auto_start');
   335              auto_start = auto_start || (up.settings && up.settings.auto_start);
   336              if (auto_start) {
   337                  plupload.each(files, function(i, file) {
   338                      up.start();
   339                  });
   340              }
   341              up.refresh(); // Reposition Flash/Silverlight
   342          });
   343  
   344          uploader.bind('BeforeUpload', function(up, file) {
   345              file.speed = file.speed || 0; // add a key named speed for file obj
   346              ctx = '';
   347  
   348              var directUpload = function(up, file, func) {
   349                  speedCalInfo.startTime = new Date().getTime();
   350                  var multipart_params_obj;
   351                  if (op.save_key) {
   352                      multipart_params_obj = {
   353                          'token': that.token
   354                      };
   355                  } else {
   356                      multipart_params_obj = {
   357                          'key': getFileKey(up, file, func),
   358                          'token': that.token
   359                      };
   360                  }
   361  
   362                  var x_vars = op.x_vars;
   363                  if (x_vars !== undefined && typeof x_vars === 'object') {
   364                      for (var x_key in x_vars) {
   365                          if (x_vars.hasOwnProperty(x_key)) {
   366                              if (typeof x_vars[x_key] === 'function') {
   367                                  multipart_params_obj['x:' + x_key] = x_vars[x_key](up, file);
   368                              } else if (typeof x_vars[x_key] !== 'object') {
   369                                  multipart_params_obj['x:' + x_key] = x_vars[x_key];
   370                              }
   371                          }
   372                      }
   373                  }
   374  
   375  
   376                  up.setOption({
   377                      'url': 'http://upload.qiniu.com/',
   378                      'multipart': true,
   379                      'chunk_size': undefined,
   380                      'multipart_params': multipart_params_obj
   381                  });
   382              };
   383  
   384  
   385              var chunk_size = up.getOption && up.getOption('chunk_size');
   386              chunk_size = chunk_size || (up.settings && up.settings.chunk_size);
   387              if (uploader.runtime === 'html5' && chunk_size) {
   388                  if (file.size < chunk_size) {
   389                      directUpload(up, file, that.key_handler);
   390                  } else {
   391                      var localFileInfo = localStorage.getItem(file.name);
   392                      var blockSize = chunk_size;
   393                      if (localFileInfo) {
   394                          localFileInfo = JSON.parse(localFileInfo);
   395                          var now = (new Date()).getTime();
   396                          var before = localFileInfo.time || 0;
   397                          var aDay = 24 * 60 * 60 * 1000; //  milliseconds
   398                          if (now - before < aDay) {
   399                              if (localFileInfo.percent !== 100) {
   400                                  if (file.size === localFileInfo.total) {
   401                                      // 通过文件名和文件大小匹配,找到对应的 localstorage 信息,恢复进度
   402                                      file.percent = localFileInfo.percent;
   403                                      file.loaded = localFileInfo.offset;
   404                                      ctx = localFileInfo.ctx;
   405  
   406                                      //  计算速度时,会用到
   407                                      speedCalInfo.isResumeUpload = true;
   408                                      speedCalInfo.resumeFilesize = localFileInfo.offset;
   409                                      if (localFileInfo.offset + blockSize > file.size) {
   410                                          blockSize = file.size - localFileInfo.offset;
   411                                      }
   412                                  } else {
   413                                      localStorage.removeItem(file.name);
   414                                  }
   415  
   416                              } else {
   417                                  // 进度100%时,删除对应的localStorage,避免 499 bug
   418                                  localStorage.removeItem(file.name);
   419                              }
   420                          } else {
   421                              localStorage.removeItem(file.name);
   422                          }
   423                      }
   424                      speedCalInfo.startTime = new Date().getTime();
   425                      up.setOption({
   426                          'url': 'http://upload.qiniu.com/mkblk/' + blockSize,
   427                          'multipart': false,
   428                          'chunk_size': chunk_size,
   429                          'required_features': "chunks",
   430                          'headers': {
   431                              'Authorization': 'UpToken ' + that.token
   432                          },
   433                          'multipart_params': {}
   434                      });
   435                  }
   436              } else {
   437                  directUpload(up, file, that.key_handler);
   438              }
   439          });
   440  
   441          uploader.bind('UploadProgress', function(up, file) {
   442              // 计算速度
   443  
   444              speedCalInfo.currentTime = new Date().getTime();
   445              var timeUsed = speedCalInfo.currentTime - speedCalInfo.startTime; // ms
   446              var fileUploaded = file.loaded || 0;
   447              if (speedCalInfo.isResumeUpload) {
   448                  fileUploaded = file.loaded - speedCalInfo.resumeFilesize;
   449              }
   450              file.speed = (fileUploaded / timeUsed * 1000).toFixed(0) || 0; // unit: byte/s
   451          });
   452  
   453          uploader.bind('ChunkUploaded', function(up, file, info) {
   454              var res = that.parseJSON(info.response);
   455  
   456              ctx = ctx ? ctx + ',' + res.ctx : res.ctx;
   457              var leftSize = info.total - info.offset;
   458              var chunk_size = up.getOption && up.getOption('chunk_size');
   459              chunk_size = chunk_size || (up.settings && up.settings.chunk_size);
   460              if (leftSize < chunk_size) {
   461                  up.setOption({
   462                      'url': 'http://upload.qiniu.com/mkblk/' + leftSize
   463                  });
   464              }
   465              localStorage.setItem(file.name, JSON.stringify({
   466                  ctx: ctx,
   467                  percent: file.percent,
   468                  total: info.total,
   469                  offset: info.offset,
   470                  time: (new Date()).getTime()
   471              }));
   472          });
   473  
   474          uploader.bind('Error', (function(_Error_Handler) {
   475              return function(up, err) {
   476                  var errTip = '';
   477                  var file = err.file;
   478                  if (file) {
   479                      switch (err.code) {
   480                          case plupload.FAILED:
   481                              errTip = '上传失败。请稍后再试。';
   482                              break;
   483                          case plupload.FILE_SIZE_ERROR:
   484                              var max_file_size = up.getOption && up.getOption('max_file_size');
   485                              max_file_size = max_file_size || (up.settings && up.settings.max_file_size);
   486                              errTip = '浏览器最大可上传' + max_file_size + '。更大文件请使用命令行工具。';
   487                              break;
   488                          case plupload.FILE_EXTENSION_ERROR:
   489                              errTip = '文件验证失败。请稍后重试。';
   490                              break;
   491                          case plupload.HTTP_ERROR:
   492                              var errorObj = that.parseJSON(err.response);
   493                              var errorText = errorObj.error;
   494                              switch (err.status) {
   495                                  case 400:
   496                                      errTip = "请求报文格式错误。";
   497                                      break;
   498                                  case 401:
   499                                      errTip = "客户端认证授权失败。请重试或提交反馈。";
   500                                      break;
   501                                  case 405:
   502                                      errTip = "客户端请求错误。请重试或提交反馈。";
   503                                      break;
   504                                  case 579:
   505                                      errTip = "资源上传成功,但回调失败。";
   506                                      break;
   507                                  case 599:
   508                                      errTip = "网络连接异常。请重试或提交反馈。";
   509                                      break;
   510                                  case 614:
   511                                      errTip = "文件已存在。";
   512                                      try {
   513                                          errorObj = that.parseJSON(errorObj.error);
   514                                          errorText = errorObj.error || 'file exists';
   515                                      } catch (e) {
   516                                          errorText = errorObj.error || 'file exists';
   517                                      }
   518                                      break;
   519                                  case 631:
   520                                      errTip = "指定空间不存在。";
   521                                      break;
   522                                  case 701:
   523                                      errTip = "上传数据块校验出错。请重试或提交反馈。";
   524                                      break;
   525                                  default:
   526                                      errTip = "未知错误。";
   527                                      break;
   528                              }
   529                              errTip = errTip + '(' + err.status + ':' + errorText + ')';
   530                              break;
   531                          case plupload.SECURITY_ERROR:
   532                              errTip = '安全配置错误。请联系网站管理员。';
   533                              break;
   534                          case plupload.GENERIC_ERROR:
   535                              errTip = '上传失败。请稍后再试。';
   536                              break;
   537                          case plupload.IO_ERROR:
   538                              errTip = '上传失败。请稍后再试。';
   539                              break;
   540                          case plupload.INIT_ERROR:
   541                              errTip = '网站配置错误。请联系网站管理员。';
   542                              uploader.destroy();
   543                              break;
   544                          default:
   545                              errTip = err.message + err.details;
   546                              break;
   547                      }
   548                      if (_Error_Handler) {
   549                          _Error_Handler(up, err, errTip);
   550                      }
   551                  }
   552                  up.refresh(); // Reposition Flash/Silverlight
   553              };
   554          })(_Error_Handler));
   555  
   556          uploader.bind('FileUploaded', (function(_FileUploaded_Handler) {
   557              return function(up, file, info) {
   558  
   559                  var last_step = function(up, file, info) {
   560                      if (op.downtoken_url) {
   561                          var ajax_downtoken = that.createAjax();
   562                          ajax_downtoken.open('POST', op.downtoken_url, true);
   563                          ajax_downtoken.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
   564                          ajax_downtoken.onreadystatechange = function() {
   565                              if (ajax_downtoken.readyState === 4) {
   566                                  if (ajax_downtoken.status === 200) {
   567                                      var res_downtoken;
   568                                      try {
   569                                          res_downtoken = that.parseJSON(ajax_downtoken.responseText);
   570                                      } catch (e) {
   571                                          throw ('invalid json format');
   572                                      }
   573                                      var info_extended = {};
   574                                      plupload.extend(info_extended, that.parseJSON(info), res_downtoken);
   575                                      if (_FileUploaded_Handler) {
   576                                          _FileUploaded_Handler(up, file, JSON.stringify(info_extended));
   577                                      }
   578                                  } else {
   579                                      uploader.trigger('Error', {
   580                                          status: ajax_downtoken.status,
   581                                          response: ajax_downtoken.responseText,
   582                                          file: file,
   583                                          code: plupload.HTTP_ERROR
   584                                      });
   585                                  }
   586                              }
   587                          };
   588                          ajax_downtoken.send('key=' + that.parseJSON(info).key + '&domain=' + op.domain);
   589                      } else if (_FileUploaded_Handler) {
   590                          _FileUploaded_Handler(up, file, info);
   591                      }
   592                  };
   593  
   594                  var res = that.parseJSON(info.response);
   595                  ctx = ctx ? ctx : res.ctx;
   596                  if (ctx) {
   597                      var key = '';
   598                      if (!op.save_key) {
   599                          key = getFileKey(up, file, that.key_handler);
   600                          key = key ? '/key/' + that.URLSafeBase64Encode(key) : '';
   601                      }
   602  
   603                      var x_vars = op.x_vars,
   604                          x_val = '',
   605                          x_vars_url = '';
   606                      if (x_vars !== undefined && typeof x_vars === 'object') {
   607                          for (var x_key in x_vars) {
   608                              if (x_vars.hasOwnProperty(x_key)) {
   609                                  if (typeof x_vars[x_key] === 'function') {
   610                                      x_val = that.URLSafeBase64Encode(x_vars[x_key](up, file));
   611                                  } else if (typeof x_vars[x_key] !== 'object') {
   612                                      x_val = that.URLSafeBase64Encode(x_vars[x_key]);
   613                                  }
   614                                  x_vars_url += '/x:' + x_key + '/' + x_val;
   615                              }
   616                          }
   617                      }
   618  
   619                      var url = 'http://upload.qiniu.com/mkfile/' + file.size + key + x_vars_url;
   620                      var ajax = that.createAjax();
   621                      ajax.open('POST', url, true);
   622                      ajax.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
   623                      ajax.setRequestHeader('Authorization', 'UpToken ' + that.token);
   624                      ajax.onreadystatechange = function() {
   625                          if (ajax.readyState === 4) {
   626                              localStorage.removeItem(file.name);
   627                              if (ajax.status === 200) {
   628                                  var info = ajax.responseText;
   629                                  last_step(up, file, info);
   630                              } else {
   631                                  uploader.trigger('Error', {
   632                                      status: ajax.status,
   633                                      response: ajax.responseText,
   634                                      file: file,
   635                                      code: -200
   636                                  });
   637                              }
   638                          }
   639                      };
   640                      ajax.send(ctx);
   641                  } else {
   642                      last_step(up, file, info.response);
   643                  }
   644  
   645              };
   646          })(_FileUploaded_Handler));
   647  
   648          return uploader;
   649      };
   650  
   651      this.getUrl = function(key) {
   652          if (!key) {
   653              return false;
   654          }
   655          key = encodeURI(key);
   656          var domain = this.domain;
   657          if (domain.slice(domain.length - 1) !== '/') {
   658              domain = domain + '/';
   659          }
   660          return domain + key;
   661      };
   662  
   663      this.imageView2 = function(op, key) {
   664          var mode = op.mode || '',
   665              w = op.w || '',
   666              h = op.h || '',
   667              q = op.q || '',
   668              format = op.format || '';
   669          if (!mode) {
   670              return false;
   671          }
   672          if (!w && !h) {
   673              return false;
   674          }
   675  
   676          var imageUrl = 'imageView2/' + mode;
   677          imageUrl += w ? '/w/' + w : '';
   678          imageUrl += h ? '/h/' + h : '';
   679          imageUrl += q ? '/q/' + q : '';
   680          imageUrl += format ? '/format/' + format : '';
   681          if (key) {
   682              imageUrl = this.getUrl(key) + '?' + imageUrl;
   683          }
   684          return imageUrl;
   685      };
   686  
   687  
   688      this.imageMogr2 = function(op, key) {
   689          var auto_orient = op['auto-orient'] || '',
   690              thumbnail = op.thumbnail || '',
   691              strip = op.strip || '',
   692              gravity = op.gravity || '',
   693              crop = op.crop || '',
   694              quality = op.quality || '',
   695              rotate = op.rotate || '',
   696              format = op.format || '',
   697              blur = op.blur || '';
   698          //Todo check option
   699  
   700          var imageUrl = 'imageMogr2';
   701  
   702          imageUrl += auto_orient ? '/auto-orient' : '';
   703          imageUrl += thumbnail ? '/thumbnail/' + thumbnail : '';
   704          imageUrl += strip ? '/strip' : '';
   705          imageUrl += gravity ? '/gravity/' + gravity : '';
   706          imageUrl += quality ? '/quality/' + quality : '';
   707          imageUrl += crop ? '/crop/' + crop : '';
   708          imageUrl += rotate ? '/rotate/' + rotate : '';
   709          imageUrl += format ? '/format/' + format : '';
   710          imageUrl += blur ? '/blur/' + blur : '';
   711  
   712          if (key) {
   713              imageUrl = this.getUrl(key) + '?' + imageUrl;
   714          }
   715          return imageUrl;
   716      };
   717  
   718      this.watermark = function(op, key) {
   719  
   720          var mode = op.mode;
   721          if (!mode) {
   722              return false;
   723          }
   724  
   725          var imageUrl = 'watermark/' + mode;
   726  
   727          if (mode === 1) {
   728              var image = op.image || '';
   729              if (!image) {
   730                  return false;
   731              }
   732              imageUrl += image ? '/image/' + this.URLSafeBase64Encode(image) : '';
   733          } else if (mode === 2) {
   734              var text = op.text ? op.text : '',
   735                  font = op.font ? op.font : '',
   736                  fontsize = op.fontsize ? op.fontsize : '',
   737                  fill = op.fill ? op.fill : '';
   738              if (!text) {
   739                  return false;
   740              }
   741              imageUrl += text ? '/text/' + this.URLSafeBase64Encode(text) : '';
   742              imageUrl += font ? '/font/' + this.URLSafeBase64Encode(font) : '';
   743              imageUrl += fontsize ? '/fontsize/' + fontsize : '';
   744              imageUrl += fill ? '/fill/' + this.URLSafeBase64Encode(fill) : '';
   745          } else {
   746              // Todo mode3
   747              return false;
   748          }
   749  
   750          var dissolve = op.dissolve || '',
   751              gravity = op.gravity || '',
   752              dx = op.dx || '',
   753              dy = op.dy || '';
   754  
   755          imageUrl += dissolve ? '/dissolve/' + dissolve : '';
   756          imageUrl += gravity ? '/gravity/' + gravity : '';
   757          imageUrl += dx ? '/dx/' + dx : '';
   758          imageUrl += dy ? '/dy/' + dy : '';
   759  
   760          if (key) {
   761              imageUrl = this.getUrl(key) + '?' + imageUrl;
   762          }
   763          return imageUrl;
   764  
   765      };
   766  
   767      this.imageInfo = function(key) {
   768          if (!key) {
   769              return false;
   770          }
   771          var url = this.getUrl(key) + '?imageInfo';
   772          var xhr = this.createAjax();
   773          var info;
   774          var that = this;
   775          xhr.open('GET', url, false);
   776          xhr.onreadystatechange = function() {
   777              if (xhr.readyState === 4 && xhr.status === 200) {
   778                  info = that.parseJSON(xhr.responseText);
   779              }
   780          };
   781          xhr.send();
   782          return info;
   783      };
   784  
   785  
   786      this.exif = function(key) {
   787          if (!key) {
   788              return false;
   789          }
   790          var url = this.getUrl(key) + '?exif';
   791          var xhr = this.createAjax();
   792          var info;
   793          var that = this;
   794          xhr.open('GET', url, false);
   795          xhr.onreadystatechange = function() {
   796              if (xhr.readyState === 4 && xhr.status === 200) {
   797                  info = that.parseJSON(xhr.responseText);
   798              }
   799          };
   800          xhr.send();
   801          return info;
   802      };
   803  
   804      this.get = function(type, key) {
   805          if (!key || !type) {
   806              return false;
   807          }
   808          if (type === 'exif') {
   809              return this.exif(key);
   810          } else if (type === 'imageInfo') {
   811              return this.imageInfo(key);
   812          }
   813          return false;
   814      };
   815  
   816  
   817      this.pipeline = function(arr, key) {
   818  
   819          var isArray = Object.prototype.toString.call(arr) === '[object Array]';
   820          var option, errOp, imageUrl = '';
   821          if (isArray) {
   822              for (var i = 0, len = arr.length; i < len; i++) {
   823                  option = arr[i];
   824                  if (!option.fop) {
   825                      return false;
   826                  }
   827                  switch (option.fop) {
   828                      case 'watermark':
   829                          imageUrl += this.watermark(option) + '|';
   830                          break;
   831                      case 'imageView2':
   832                          imageUrl += this.imageView2(option) + '|';
   833                          break;
   834                      case 'imageMogr2':
   835                          imageUrl += this.imageMogr2(option) + '|';
   836                          break;
   837                      default:
   838                          errOp = true;
   839                          break;
   840                  }
   841                  if (errOp) {
   842                      return false;
   843                  }
   844              }
   845              if (key) {
   846                  imageUrl = this.getUrl(key) + '?' + imageUrl;
   847                  var length = imageUrl.length;
   848                  if (imageUrl.slice(length - 1) === '|') {
   849                      imageUrl = imageUrl.slice(0, length - 1);
   850                  }
   851              }
   852              return imageUrl;
   853          }
   854          return false;
   855      };
   856  
   857  }
   858  
   859  var Qiniu = new QiniuJsSDK();