Skip to content

Commit cb8d2c1

Browse files
committed
Merge pull request #173 from wangxiao/master
[bugfix] 海外节点文件上传通过服务器中转到 CDN。
2 parents c7661dc + 4247f3e commit cb8d2c1

File tree

6 files changed

+107
-109
lines changed

6 files changed

+107
-109
lines changed

README.md

Lines changed: 14 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -13,78 +13,31 @@ JavaScript SDK for [LeanCloud](http://leancloud.cn/).
1313

1414
* fork 这个项目
1515
* 在本地进行调试,`npm install` 安装相关依赖
16-
* 执行 `gulp browserify` 会生成浏览器 SDK
17-
* 服务环境可以通过单元测试调试
18-
* 确保 `gulp test` 的测试全部通过,浏览器环境打开 test/test.html
19-
* 提交并发起 PR
16+
* 执行 `gulp browserify` 会生成浏览器 SDK
17+
* 执行 `gulp release` 会生成全部版本的 SDK
18+
* 服务环境可以通过单元测试调试 `gulp test`,浏览器环境打开 test/test.html
19+
* 确保测试全部通过
20+
* 提交并发起 Pull Request
2021

2122
项目的目录结构说明如下:
2223

2324
```
24-
├── README.md
25+
├── README.md // 说明文档
2526
├── bower.json
2627
├── changelog.md
2728
├── dist // 编译之后生成的文件将会在此目录下
2829
├── gulpfile.js
2930
├── lib
30-
│ ├── acl.js
3131
│ ├── av-browser.js // 浏览器环境入口文件,将会被 browserify 编译
3232
│ ├── av-browser-core.js // 浏览器环境入口文件,只包含核心依赖,将会被 browserify 编译
3333
│ ├── av.js // node.js 环境入口文件
3434
│ ├── bigquery.js
3535
│ ├── browserify-wrapper // 针对 node.js 与浏览器环境之间差异的不同实现
36-
│ │ ├── localstorage-browser.js
37-
│ │ ├── parse-base64-browser.js
38-
│ │ ├── parse-base64.js
39-
│ │ ├── upload-browser.js
40-
│ │ ├── upload.js
41-
│ │ └── xmlhttprequest-browser.js
42-
│ ├── cloud.js
43-
│ ├── cloudfunction.js
44-
│ ├── collection.js
45-
│ ├── error.js
46-
│ ├── event.js
47-
│ ├── facebook.js
48-
│ ├── file.js
49-
│ ├── geopoint.js
50-
│ ├── history.js
51-
│ ├── insight.js
52-
│ ├── object.js
53-
│ ├── op.js
54-
│ ├── promise.js
55-
│ ├── push.js
56-
│ ├── query.js
57-
│ ├── relation.js
58-
│ ├── role.js
59-
│ ├── router.js
60-
│ ├── search.js
61-
│ ├── status.js
62-
│ ├── user.js
63-
│ ├── utils.js
64-
│ ├── version.js
65-
│ └── view.js
36+
│ └── ...
6637
├── package.json
6738
├── readme.txt
6839
├── test // 单元测试
69-
│ ├── acl.js
70-
│ ├── bigquery.js
71-
│ ├── cloud.js
72-
│ ├── collection.js
73-
│ ├── error.js
74-
│ ├── file.html
75-
│ ├── file.js
76-
│ ├── file_blob.html
77-
│ ├── file_form.html
78-
│ ├── geopoints.js
79-
│ ├── object.js
80-
│ ├── promise.js
81-
│ ├── query.js
82-
│ ├── search.js
83-
│ ├── sms.js
84-
│ ├── status.js
85-
│ ├── test.html
86-
│ ├── test.js
87-
│ └── user.js
40+
│ └── ...
8841
└── tools // 构建中依赖的第三方工具
8942
```
9043

@@ -94,30 +47,14 @@ JavaScript SDK for [LeanCloud](http://leancloud.cn/).
9447
* lib/version.js
9548
* package.json
9649
* bower.json
97-
9850
* 修改 Changelog
99-
100-
* 打包 Release
101-
102-
```
103-
gulp release
104-
```
105-
51+
* 打包(执行 `gulp release`
10652
* 提交当前所有代码
10753
* 版本号相关修改
10854
* change log
10955
* dist/ 目录中的新代码
110-
111-
* 提交代码,发 pull request
112-
113-
* (merge 后)Github 生成 release 包(for bower)
114-
115-
* 发布到 npm(需 npm 协作者身份)
116-
```
117-
npm publish
118-
```
119-
120-
* 发布到 CDN(需要七牛权限)
121-
```
122-
gulp upload
123-
```
56+
* 提交代码,发 Pull Request
57+
* 通过 review,merge 代码
58+
* Github 生成 release 包(for bower)
59+
* 发布到 npm,需 npm 协作者身份(执行 `npm publish`
60+
* 发布到 CDN,需要七牛权限(执行 `gulp upload`

gulpfile.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,13 @@ gulp.task('upload', ['compress-scripts'], function(cb) {
144144
});
145145
});
146146

147-
148147
gulp.task('release', [
149148
'browserify',
150149
'uglify',
151150
'compress-scripts',
151+
]);
152+
153+
gulp.task('doc', [
152154
'docs',
153155
'compress-docs'
154156
]);

lib/av-browser.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@
22

33
var AV = require('./AV');
44

5-
global.AV = AV;
5+
global.AV = global.AV || {};
6+
7+
// 防止多个 SDK 互相覆盖 AV 命名空间
8+
for (var k in AV) {
9+
global.AV[k] = AV[k];
10+
}

lib/av.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ AV.XMLHttpRequest = require('./browserify-wrapper/xmlhttprequest').XMLHttpReques
1616
AV.localStorage = require('./localstorage');
1717

1818
// 以下模块为了兼容原有代码,使用这种加载方式。
19-
// The module order is important.
2019
require('./utils')(AV);
2120
require('./error')(AV);
2221
require('./event')(AV);
@@ -27,18 +26,21 @@ require('./relation')(AV);
2726
require('./file')(AV);
2827
require('./object')(AV);
2928
require('./role')(AV);
30-
require('./collection')(AV);
31-
require('./view')(AV);
3229
require('./user')(AV);
3330
require('./query')(AV);
34-
require('./facebook')(AV);
35-
require('./history')(AV);
36-
require('./router')(AV);
3731
require('./cloudfunction')(AV);
3832
require('./push')(AV);
3933
require('./status')(AV);
4034
require('./search')(AV);
4135
require('./insight')(AV);
4236
require('./bigquery')(AV);
4337

44-
AV.AV = AV; // Backward compatibility
38+
// 以下模块是旧模块,与 core 版本的区别,准备去掉这些方法
39+
require('./collection')(AV);
40+
require('./view')(AV);
41+
require('./facebook')(AV);
42+
require('./history')(AV);
43+
require('./router')(AV);
44+
45+
// Backward compatibility
46+
AV.AV = AV;

lib/file.js

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ module.exports = function(AV) {
5050
return chunks.join("");
5151
};
5252

53+
var dataURLToBase64 = function(base64) {
54+
if (base64.split(',')[0] && base64.split(',')[0].indexOf('base64') >= 0) {
55+
base64 = base64.split(',')[1];
56+
}
57+
return base64;
58+
};
59+
5360
// A list of file extensions to mime types as found here:
5461
// http://stackoverflow.com/questions/58510/using-net-how-can-you-find-the-
5562
// mime-type-of-a-file-based-on-the-file-signature
@@ -317,6 +324,10 @@ module.exports = function(AV) {
317324
*/
318325
AV.File = function(name, data, type) {
319326
this._name = name;
327+
328+
// 用来存储转换后要上传的 base64 String
329+
this._base64 = '';
330+
320331
var currentUser;
321332
try {
322333
currentUser = AV.User.current();
@@ -337,19 +348,22 @@ module.exports = function(AV) {
337348
this._guessedType = guessedType;
338349

339350
if (_.isArray(data)) {
340-
this._source = AV.Promise.as(encodeBase64(data), guessedType);
351+
this._base64 = encodeBase64(data);
352+
this._source = AV.Promise.as(this._base64, guessedType);
341353
this._metaData.size = data.length;
342354
} else if (data && data.base64) {
343355
var parseBase64 = require('./browserify-wrapper/parse-base64');
344356
var dataBase64 = parseBase64(data.base64, guessedType);
357+
this._base64 = dataURLToBase64(data.base64);
345358
this._source = AV.Promise.as(dataBase64, guessedType);
346359
} else if (data && data.blob) {
347360
this._source = AV.Promise.as(data.blob, guessedType);
348361
} else if (typeof(File) !== "undefined" && data instanceof File) {
349362
this._source = AV.Promise.as(data, guessedType);
350363
} else if(AV._isNode && global.Buffer.isBuffer(data)) {
351364
// use global.Buffer to prevent browserify pack Buffer module
352-
this._source = AV.Promise.as(data.toString('base64'), guessedType);
365+
this._base64 = data.toString('base64');
366+
this._source = AV.Promise.as(this._base64, guessedType);
353367
this._metaData.size = data.length;
354368
} else if (_.isString(data)) {
355369
throw "Creating a AV.File from a String is not yet supported.";
@@ -567,10 +581,12 @@ module.exports = function(AV) {
567581
}
568582
var self = this;
569583
if (!self._previousSave) {
570-
if(self._source) {
584+
// 如果是国内节点
585+
if(self._source && AV.serverURL === AV._config.cnApiUrl) {
586+
// 通过国内 CDN 服务商上传
571587
var upload = require('./browserify-wrapper/upload');
572588
upload(self, AV, saveOptions);
573-
} else if(self._url && self._metaData['__source'] == 'external') {
589+
} else if (self._url && self._metaData['__source'] == 'external') {
574590
//external link file.
575591
var data = {
576592
name: self._name,
@@ -579,7 +595,7 @@ module.exports = function(AV) {
579595
mime_type: self._guessedType,
580596
url: self._url
581597
};
582-
self._previousSave = AV._request("files", self._name, null, 'POST', data).then(function(response) {
598+
self._previousSave = AV._request('files', self._name, null, 'POST', data).then(function(response) {
583599
self._name = response.name;
584600
self._url = response.url;
585601
self.id = response.objectId;
@@ -588,6 +604,34 @@ module.exports = function(AV) {
588604
}
589605
return self;
590606
});
607+
} else if (AV.serverURL !== AV._config.cnApiUrl) {
608+
// 海外节点,通过 LeanCloud 服务器中转
609+
self._previousSave = self._source.then(function(file, type) {
610+
var data = {
611+
base64: '',
612+
_ContentType: type,
613+
ACL: self._acl,
614+
mime_type: type,
615+
metaData: self._metaData,
616+
};
617+
// 判断是否数据已经是 base64
618+
if (self._base64) {
619+
data.base64 = self._base64;
620+
return AV._request('files', self._name, null, 'POST', data);
621+
} else {
622+
return readAsync(file).then(function(base64) {
623+
data.base64 = base64;
624+
return AV._request('files', self._name, null, 'POST', data);
625+
});
626+
}
627+
}).then(function(response) {
628+
self._name = response.name;
629+
self._url = response.url;
630+
self.id = response.objectId;
631+
if(response.size)
632+
self._metaData.size = response.size;
633+
return self;
634+
});
591635
}
592636
}
593637
return self._previousSave._thenRunCallbacks(options);

lib/utils.js

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ var _ = require('underscore');
66
XMLHttpRequest: false, XDomainRequest: false, exports: false,
77
require: false */
88
module.exports = function(AV) {
9+
10+
// 挂载一些配置
11+
AV._config = AV._config || {};
12+
_.extend(AV._config, {
13+
cnApiUrl: 'https://api.leancloud.cn',
14+
usApiUrl: 'https://us-api.leancloud.cn'
15+
});
16+
917
/**
1018
* Contains all AV API classes and functions.
1119
* @name AV
@@ -71,9 +79,6 @@ module.exports = function(AV) {
7179
return child;
7280
};
7381

74-
// Set the server for AV to talk to.
75-
AV.serverURL = "https://api.leancloud.cn";
76-
7782
// Check whether we are running in Node.js.
7883
if (typeof(process) !== "undefined" &&
7984
process.versions &&
@@ -147,20 +152,22 @@ module.exports = function(AV) {
147152
};
148153
}
149154

155+
/**
156+
*Use china avoscloud API service
157+
*/
158+
AV.useAVCloudCN = function(){
159+
AV.serverURL = AV._config.cnApiUrl;
160+
};
150161

151-
/**
152-
*Use china avoscloud API service:https://cn.avoscloud.com
153-
*/
154-
AV.useAVCloudCN = function(){
155-
AV.serverURL = "https://leancloud.cn";
156-
};
162+
/**
163+
*Use USA avoscloud API service
164+
*/
165+
AV.useAVCloudUS = function(){
166+
AV.serverURL = AV._config.usApiUrl;
167+
};
157168

158-
/**
159-
*Use USA avoscloud API service:https://us.avoscloud.com
160-
*/
161-
AV.useAVCloudUS = function(){
162-
AV.serverURL = "https://us-api.leancloud.cn";
163-
};
169+
// 默认使用国内节点
170+
AV.useAVCloudCN();
164171

165172
/**
166173
* Returns prefix for localStorage keys used by this instance of AV.
@@ -422,7 +429,7 @@ module.exports = function(AV) {
422429
return AV._getInstallationId();
423430
}).then(function(_InstallationId) {
424431
dataObject._InstallationId = _InstallationId;
425-
432+
426433
var data = JSON.stringify(dataObject);
427434
return AV._ajax(method, url, data).then(null, function(response) {
428435
// Transform the error into an instance of AV.Error by trying to parse
@@ -552,8 +559,9 @@ module.exports = function(AV) {
552559
if (value.__op) {
553560
return AV.Op._decode(value);
554561
}
562+
var className;
555563
if (value.__type === "Pointer") {
556-
var className = value.className;
564+
className = value.className;
557565
var pointer = AV.Object._create(className);
558566
if(value.createdAt){
559567
delete value.__type;
@@ -566,7 +574,7 @@ module.exports = function(AV) {
566574
}
567575
if (value.__type === "Object") {
568576
// It's an Object included in a query result.
569-
var className = value.className;
577+
className = value.className;
570578
delete value.__type;
571579
delete value.className;
572580
var object = AV.Object._create(className);

0 commit comments

Comments
 (0)