Skip to content

Commit d8767c4

Browse files
committed
feat(File): support COS (#272)
1 parent fc74002 commit d8767c4

File tree

12 files changed

+141
-121
lines changed

12 files changed

+141
-121
lines changed

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"test": "gulp test"
1212
},
1313
"dependencies": {
14+
"form-data": "^1.0.0-rc4",
1415
"localstorage-memory": "^1.0.1",
1516
"md5": "^2.0.0",
1617
"qiniu": "6.1.3",
@@ -49,13 +50,15 @@
4950
"browser": {
5051
"react-native": false,
5152
"./src/browserify-wrapper/ajax.js": "./src/browserify-wrapper/ajax-browser.js",
52-
"./src/browserify-wrapper/upload.js": "./src/browserify-wrapper/upload-browser.js",
53+
"./src/uploader/qiniu.js": "./src/uploader/qiniu-browser.js",
5354
"./src/browserify-wrapper/localStorage.js": "./src/browserify-wrapper/localstorage-browser.js",
5455
"./src/browserify-wrapper/parse-base64.js": "./src/browserify-wrapper/parse-base64-browser.js",
56+
"./src/uploader/cos.js": "./src/uploader/cos-browser.js",
5557
"./dist/node/browserify-wrapper/ajax.js": "./dist/node/browserify-wrapper/ajax-browser.js",
56-
"./dist/node/browserify-wrapper/upload.js": "./dist/node/browserify-wrapper/upload-browser.js",
58+
"./dist/node/uploader/qiniu.js": "./dist/node/uploader/qiniu-browser.js",
5759
"./dist/node/browserify-wrapper/localStorage.js": "./dist/node/browserify-wrapper/localstorage-browser.js",
58-
"./dist/node/browserify-wrapper/parse-base64.js": "./dist/node/browserify-wrapper/parse-base64-browser.js"
60+
"./dist/node/browserify-wrapper/parse-base64.js": "./dist/node/browserify-wrapper/parse-base64-browser.js",
61+
"./dist/node/uploader/cos.js": "./dist/node/uploader/cos-browser.js"
5962
},
6063
"eslintConfig": {
6164
"env": {

src/browserify-wrapper/ajax-browser.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@
88
const AVPromise = require('../promise');
99
const debug = require('debug')('ajax');
1010

11-
const ajax = (method, url, data, headers = {}) => {
11+
const ajax = (method, url, data, headers = {}, onprogress) => {
1212
debug(method, url, data, headers);
1313

1414
const promise = new AVPromise();
1515

1616
let handled = false;
1717
const xhr = new global.XMLHttpRequest();
18+
19+
if (onprogress && xhr.upload) {
20+
xhr.upload.onprogress = onprogress;
21+
}
22+
1823
xhr.onreadystatechange = () => {
1924
if (xhr.readyState === 4) {
2025
if (handled) {
@@ -48,7 +53,7 @@ const ajax = (method, url, data, headers = {}) => {
4853
xhr.setRequestHeader(name, headers[name]);
4954
}
5055

51-
xhr.send(JSON.stringify(data));
56+
xhr.send(data);
5257
return promise;
5358
};
5459

src/browserify-wrapper/ajax.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ module.exports = function _ajax(method, resourceUrl, data, headers = {}) {
6464
promise.reject(err);
6565
});
6666

67-
req.end(JSON.stringify(data));
67+
req.end(data);
6868
return promise;
6969
};

src/browserify-wrapper/upload-browser.js

Lines changed: 0 additions & 68 deletions
This file was deleted.

src/browserify-wrapper/upload.js

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/file.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
'use strict';
77

88
const _ = require('underscore');
9+
const cos = require('./uploader/cos');
10+
const qiniu = require('./uploader/qiniu');
911

1012
module.exports = function(AV) {
1113

@@ -617,7 +619,7 @@ module.exports = function(AV) {
617619
* @return {AV.Promise} Resolved with the response
618620
* @private
619621
*/
620-
_qiniuToken: function(type) {
622+
_fileToken: function(type, route = 'fileTokens') {
621623
const name = this.attributes.name;
622624
//Create 16-bits uuid as qiniu key.
623625
const extName = extname(name);
@@ -636,7 +638,7 @@ module.exports = function(AV) {
636638
this.attributes.metaData.mime_type = type;
637639
}
638640
this._qiniu_key = key;
639-
return AV._request("qiniu", null, null, 'POST', data);
641+
return AV._request(route, null, null, 'POST', data);
640642
},
641643

642644
/**
@@ -670,8 +672,22 @@ module.exports = function(AV) {
670672
var isCnNodeFlag = isCnNode();
671673
if (this._source && isCnNodeFlag) {
672674
// 通过国内 CDN 服务商上传
673-
var upload = require('./browserify-wrapper/upload');
674-
upload(this, AV, saveOptions);
675+
this._previousSave = this._source.then((data, type) => {
676+
return this._fileToken(type).catch(() => this._fileToken(type, 'qiniu'))
677+
.then(uploadInfo => {
678+
let uploadPromise;
679+
if (uploadInfo.provider === 'qcloud') {
680+
uploadPromise = cos(uploadInfo, data, this, saveOptions);
681+
} else {
682+
uploadPromise = qiniu(uploadInfo, data, this, saveOptions);
683+
}
684+
return uploadPromise.catch(err => {
685+
//destroy this file object when upload fails.
686+
this.destroy();
687+
throw err;
688+
});
689+
});
690+
});
675691
} else if (this.attributes.url && this.attributes.metaData.__source === 'external') {
676692
//external link file.
677693
var data = {

src/uploader/cos-browser.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
const ajax = require('../browserify-wrapper/ajax.js');
4+
5+
module.exports =function upload(uploadInfo, data, file, saveOptions) {
6+
file.attributes.url = uploadInfo.url;
7+
file._bucket = uploadInfo.bucket;
8+
file.id = uploadInfo.objectId;
9+
const uploadUrl = uploadInfo.upload_url + "?sign=" + encodeURIComponent(uploadInfo.token);
10+
const formData = new FormData();
11+
formData.append('fileContent', data);
12+
formData.append('op', 'upload');
13+
14+
return ajax('POST', uploadUrl, formData, undefined, saveOptions.onProgress)
15+
.then(() => file);
16+
};

src/uploader/cos.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
const FormData = require('form-data');
3+
4+
const ajax = require('../browserify-wrapper/ajax.js');
5+
const Promise = require('../promise');
6+
const debug = require('debug')('cos');
7+
8+
module.exports =function upload(uploadInfo, data, file) {
9+
file.attributes.url = uploadInfo.url;
10+
file._bucket = uploadInfo.bucket;
11+
file.id = uploadInfo.objectId;
12+
const uploadUrl = uploadInfo.upload_url;
13+
const body = new Buffer(data, 'base64');
14+
debug(uploadUrl, data);
15+
const formData = new FormData();
16+
formData.append('fileContent', body);
17+
formData.append('op', 'upload');
18+
19+
const promise = new Promise();
20+
21+
const request = formData.submit(uploadUrl, function(err, res) {
22+
debug(err, res.statusCode);
23+
if (err) {
24+
promise.reject(err);
25+
} else {
26+
promise.resolve(file);
27+
}
28+
});
29+
request.setHeader('Authorization', uploadInfo.token);
30+
return promise;
31+
};

src/uploader/qiniu-browser.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* 每位工程师都有保持代码优雅的义务
3+
* Each engineer has a duty to keep the code elegant
4+
**/
5+
6+
'use strict';
7+
8+
const ajax = require('../browserify-wrapper/ajax.js');
9+
10+
module.exports = function upload(uploadInfo, data, file, saveOptions) {
11+
file.attributes.url = uploadInfo.url;
12+
file._bucket = uploadInfo.bucket;
13+
file.id = uploadInfo.objectId;
14+
//Get the uptoken to upload files to qiniu.
15+
const uptoken = uploadInfo.token;
16+
const formData = new FormData();
17+
formData.append('file', data);
18+
formData.append('name', file.attributes.name);
19+
formData.append('key', file._qiniu_key);
20+
formData.append('token', uptoken);
21+
22+
return ajax('POST', 'https://up.qbox.me', formData, undefined, saveOptions.onProgress)
23+
.then(() => file);
24+
};

src/uploader/qiniu.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* 每位工程师都有保持代码优雅的义务
3+
* Each engineer has a duty to keep the code elegant
4+
**/
5+
6+
'use strict';
7+
8+
//Use qiniu sdk to upload files to qiniu.
9+
const qiniu = require('qiniu');
10+
const Promise = require('../promise');
11+
12+
module.exports =function upload(uploadInfo, data, file) {
13+
file.attributes.url = uploadInfo.url;
14+
file._bucket = uploadInfo.bucket;
15+
file.id = uploadInfo.objectId;
16+
//Get the uptoken to upload files to qiniu.
17+
const uptoken = uploadInfo.token;
18+
const promise = new Promise();
19+
const extra = new qiniu.io.PutExtra();
20+
if(file.attributes.metaData.mime_type)
21+
extra.mimeType = file.attributes.metaData.mime_type;
22+
const body = new Buffer(data, 'base64');
23+
qiniu.io.put(uptoken, file._qiniu_key, body, extra, function(err, ret) {
24+
delete file._qiniu_key;
25+
delete file.attributes.base64;
26+
if(!err) {
27+
promise.resolve(file);
28+
} else {
29+
promise.reject(err);
30+
}
31+
});
32+
return promise;
33+
};

0 commit comments

Comments
 (0)