|
329 | 329 | this._metaData.size = data.length; |
330 | 330 | } else if (data && data.base64) { |
331 | 331 | this._source = AV.Promise.as(data.base64, guessedType); |
| 332 | + } else if (data && data.blob) { |
| 333 | + this._source = AV.Promise.as(data.blob, guessedType); |
| 334 | + this._isBlob = true; |
332 | 335 | } else if (typeof(File) !== "undefined" && data instanceof File) { |
333 | 336 | this._source = readAsync(data, type); |
334 | 337 | } else if(AV._isNode && Buffer.isBuffer(data)) { |
|
499 | 502 | return request._thenRunCallbacks(options); |
500 | 503 | }, |
501 | 504 |
|
| 505 | + /** |
| 506 | + * Request Qiniu upload token |
| 507 | + * @param {string} type |
| 508 | + * @return {AV.Promise} Resolved with the response |
| 509 | + * @private |
| 510 | + */ |
| 511 | + _qiniuToken: function(type) { |
| 512 | + var self = this; |
| 513 | + //Create 16-bits uuid as qiniu key. |
| 514 | + var extName; |
| 515 | + if (AV._isNode) { |
| 516 | + var path = require('path'); |
| 517 | + extName = path.extname(self._name); |
| 518 | + } else { |
| 519 | + var nameParts = self._name.split('.'); |
| 520 | + extName = '.' + nameParts[nameParts.length - 1]; |
| 521 | + } |
| 522 | + var hexOctet = function() { |
| 523 | + return Math.floor((1+Math.random())*0x10000).toString(16).substring(1); |
| 524 | + }; |
| 525 | + var key = hexOctet() + hexOctet() + hexOctet() + hexOctet() + hexOctet() |
| 526 | + + extName; |
| 527 | + |
| 528 | + var data = { |
| 529 | + key: key, |
| 530 | + ACL: self._acl, |
| 531 | + name:self._name, |
| 532 | + mime_type: type, |
| 533 | + metaData: self._metaData |
| 534 | + }; |
| 535 | + if(type && self._metaData.mime_type == null) |
| 536 | + self._metaData.mime_type = type; |
| 537 | + self._qiniu_key = key; |
| 538 | + return AV._request("qiniu", null, null, 'POST', data); |
| 539 | + }, |
| 540 | + |
| 541 | + /** |
| 542 | + * @callback UploadProgressCallback |
| 543 | + * @param {XMLHttpRequestProgressEvent} event - The progress event with 'loaded' and 'total' attributes |
| 544 | + */ |
502 | 545 | /** |
503 | 546 | * Saves the file to the AV cloud. |
| 547 | + * @param {Object} saveOptions |
| 548 | + * @param {UploadProgressCallback} [saveOptions.onProgress] |
504 | 549 | * @param {Object} options A Backbone-style options object. |
505 | 550 | * @return {AV.Promise} Promise that is resolved when the save finishes. |
506 | 551 | */ |
507 | | - save: function(options) { |
| 552 | + save: function() { |
| 553 | + var options = null; |
| 554 | + var saveOptions = {}; |
| 555 | + if(arguments.length === 1) { |
| 556 | + options = arguments[0]; |
| 557 | + } else if(arguments.length === 2) { |
| 558 | + saveOptions = arguments[0]; |
| 559 | + options = arguments[1]; |
| 560 | + } |
508 | 561 | var self = this; |
509 | 562 | if (!self._previousSave) { |
510 | 563 | if(self._source){ |
511 | 564 | if(AV._isNode){ |
512 | | - //Use qiniu sdk to upload files to qiniu. |
513 | | - var qiniu = require('qiniu'); |
514 | | - var path = require('path'); |
515 | 565 | self._previousSave = self._source.then(function(base64, type) { |
516 | | - //Create 16-bits uuid as qiniu key. |
517 | | - var hexOctet = function() { |
518 | | - return Math.floor((1+Math.random())*0x10000).toString(16).substring(1); |
519 | | - }; |
520 | | - var key = hexOctet() + hexOctet() + hexOctet() + hexOctet() |
521 | | - + path.extname(self._name); |
522 | | - var data = { |
523 | | - key: key, |
524 | | - ACL: self._acl, |
525 | | - name:self._name, |
526 | | - mime_type: type, |
527 | | - metaData: self._metaData, |
528 | | - }; |
529 | | - if(type && self._metaData.mime_type == null) |
530 | | - self._metaData.mime_type = type; |
531 | | - self._qiniu_key = key; |
532 | 566 | self._base64 = base64; |
533 | | - return AV._request("qiniu", null, null, 'POST', data); |
| 567 | + return self._qiniuToken(type); |
534 | 568 | }).then(function(response) { |
| 569 | + //Use qiniu sdk to upload files to qiniu. |
| 570 | + var qiniu = require('qiniu'); |
535 | 571 | self._url = response.url; |
536 | 572 | self._bucket = response.bucket; |
537 | 573 | self.id = response.objectId; |
|
553 | 589 | self.destroy(); |
554 | 590 | } |
555 | 591 | }); |
| 592 | + return promise; |
| 593 | + }); |
| 594 | + } else if (this._isBlob) { |
| 595 | + self._previousSave = self._source.then(function(blob, type) { |
| 596 | + self._blob = blob; |
| 597 | + return self._qiniuToken(type); |
| 598 | + }).then(function(response) { |
| 599 | + self._url = response.url; |
| 600 | + self._bucket = response.bucket; |
| 601 | + self.id = response.objectId; |
| 602 | + //Get the uptoken to upload files to qiniu. |
| 603 | + var uptoken = response.token; |
| 604 | + |
| 605 | + var data = new FormData(); |
| 606 | + data.append("file", self._blob, self._name); |
| 607 | + data.append("key", self._qiniu_key); |
| 608 | + data.append("token", uptoken); |
| 609 | + |
| 610 | + var promise = new AV.Promise(); |
| 611 | + var handled = false; |
| 612 | + |
| 613 | + var xhr = new AV.XMLHttpRequest(); |
| 614 | + |
| 615 | + xhr.upload.addEventListener('progress', function(e) { |
| 616 | + if (e.lengthComputable) { |
| 617 | + saveOptions.onProgress && saveOptions.onProgress(e); |
| 618 | + } |
| 619 | + }, false); |
| 620 | + |
| 621 | + xhr.onreadystatechange = function() { |
| 622 | + if (xhr.readyState === 4) { |
| 623 | + if (handled) { |
| 624 | + return; |
| 625 | + } |
| 626 | + handled = true; |
| 627 | + |
| 628 | + delete self._qiniu_key; |
| 629 | + delete self._blob; |
| 630 | + if (xhr.status >= 200 && xhr.status < 300) { |
| 631 | + var response; |
| 632 | + try { |
| 633 | + response = JSON.parse(xhr.responseText); |
| 634 | + } catch (e) { |
| 635 | + promise.reject(e); |
| 636 | + self.destroy(); |
| 637 | + } |
| 638 | + if (response) { |
| 639 | + promise.resolve(self); |
| 640 | + } else { |
| 641 | + promise.reject(response); |
| 642 | + } |
| 643 | + } else { |
| 644 | + promise.reject(xhr); |
| 645 | + self.destroy(); |
| 646 | + } |
| 647 | + } |
| 648 | + }; |
| 649 | + xhr.open('POST', 'http://upload.qiniu.com', true); |
| 650 | + xhr.send(data); |
| 651 | + |
556 | 652 | return promise; |
557 | 653 | }); |
558 | 654 | } else { |
|
563 | 659 | _ContentType: type, |
564 | 660 | ACL: self._acl, |
565 | 661 | mime_type: type, |
566 | | - metaData: self._metaData, |
| 662 | + metaData: self._metaData |
567 | 663 | }; |
568 | 664 | return AV._request("files", self._name, null, 'POST', data); |
569 | 665 | }).then(function(response) { |
|
0 commit comments