6
6
const request = require ( 'superagent' ) ;
7
7
const debug = require ( 'debug' ) ( 'request' ) ;
8
8
const md5 = require ( 'md5' ) ;
9
- const Promise = require ( './promise' ) ;
9
+ const AVPromise = require ( './promise' ) ;
10
10
const Cache = require ( './cache' ) ;
11
11
const AVError = require ( './error' ) ;
12
12
const AV = require ( './av' ) ;
13
+ const _ = require ( 'underscore' ) ;
14
+
15
+ const getServerURLPromise = new AVPromise ( ) ;
16
+
17
+ // 服务器请求的节点 host
18
+ const API_HOST = {
19
+ cn : 'https://api.leancloud.cn' ,
20
+ us : 'https://us-api.leancloud.cn' ,
21
+ } ;
13
22
14
23
// 计算 X-LC-Sign 的签名方法
15
24
const sign = ( key , isMasterKey ) => {
@@ -65,7 +74,7 @@ const checkRouter = (router) => {
65
74
const ajax = ( method , resourceUrl , data , headers = { } , onprogress ) => {
66
75
debug ( method , resourceUrl , data , headers ) ;
67
76
68
- const promise = new Promise ( ) ;
77
+ const promise = new AVPromise ( ) ;
69
78
const req = request ( method , resourceUrl )
70
79
. set ( headers )
71
80
. send ( data )
@@ -109,7 +118,7 @@ const setHeaders = (sessionToken) => {
109
118
headers [ 'User-Agent' ] = AV . _config . userAgent || `AV/${ AV . version } ; Node.js/${ process . version } ` ;
110
119
}
111
120
112
- const promise = new Promise ( ) ;
121
+ const promise = new AVPromise ( ) ;
113
122
114
123
// Pass the session token
115
124
if ( sessionToken ) {
@@ -179,20 +188,23 @@ const cacheServerURL = (serverURL, ttl) => {
179
188
if ( typeof ttl !== 'number' ) {
180
189
ttl = 3600 ;
181
190
}
182
- Cache . set ( 'APIServerURL' , serverURL , ttl * 1000 ) ;
191
+ return Cache . setAsync ( 'APIServerURL' , serverURL , ttl * 1000 ) ;
183
192
} ;
184
193
185
194
// handle AV._request Error
186
195
const handleError = ( res ) => {
187
- const promise = new Promise ( ) ;
196
+ const promise = new AVPromise ( ) ;
188
197
/**
189
198
When API request need to redirect to the right location,
190
199
can't use browser redirect by http status 307, as the reason of CORS,
191
200
so API server response http status 410 and the param "location" for this case.
192
201
*/
193
202
if ( res . statusCode === 410 ) {
194
- cacheServerURL ( res . response . api_server , res . response . ttl ) ;
195
- promise . resolve ( res . response . location ) ;
203
+ cacheServerURL ( res . response . api_server , res . response . ttl ) . then ( ( ) => {
204
+ promise . resolve ( res . response . location ) ;
205
+ } ) . catch ( ( error ) => {
206
+ promise . reject ( error ) ;
207
+ } ) ;
196
208
} else {
197
209
let errorJSON = { code : - 1 , error : res . responseText } ;
198
210
if ( res . response && res . response . code ) {
@@ -213,40 +225,44 @@ const handleError = (res) => {
213
225
return promise ;
214
226
} ;
215
227
216
- const setServerUrlByRegion = ( region = 'cn' ) => {
217
- // 服务器请求的节点 host
218
- const API_HOST = {
219
- cn : 'https://api.leancloud.cn' ,
220
- us : 'https://us-api.leancloud.cn' ,
221
- } ;
228
+ const setServerUrl = ( serverURL ) => {
229
+ AV . _config . APIServerURL = `https://${ serverURL } ` ;
222
230
223
- const AVConfig = AV . _config ;
224
- AVConfig . region = region ;
231
+ // 根据新 URL 重新设置区域
232
+ const newRegion = _ . findKey ( API_HOST , item => item === AV . _config . APIServerURL ) ;
233
+ if ( newRegion ) {
234
+ AV . _config . region = newRegion ;
235
+ }
236
+ } ;
237
+
238
+ const refreshServerUrl = ( ) => {
239
+ const url = `https://app-router.leancloud.cn/1/route?appId=${ AV . applicationId } ` ;
240
+ return ajax ( 'get' , url ) . then ( servers => {
241
+ if ( servers . api_server ) {
242
+ setServerUrl ( servers . api_server ) ;
243
+ return cacheServerURL ( servers . api_server , servers . ttl ) ;
244
+ }
245
+ } ) ;
246
+ } ;
247
+
248
+ const setServerUrlByRegion = ( region = 'cn' ) => {
225
249
// 如果用户在 init 之前设置了 APIServerURL,则跳过请求 router
226
- if ( AVConfig . APIServerURL ) {
250
+ if ( AV . _config . APIServerURL ) {
227
251
return ;
228
252
}
229
- AVConfig . APIServerURL = API_HOST [ region ] ;
230
- if ( region === 'cn' ) {
231
- Cache . get ( 'APIServerURL' ) . then ( cachedServerURL => {
232
- if ( cachedServerURL ) {
233
- return cachedServerURL ;
234
- } else {
235
- return ajax ( 'get' , `https://app-router.leancloud.cn/1/route?appId=${ AV . applicationId } ` )
236
- . then ( servers => {
237
- if ( servers . api_server ) {
238
- cacheServerURL ( servers . api_server , servers . ttl ) ;
239
- return servers . api_server ;
240
- }
241
- } ) ;
242
- }
243
- } ) . then ( serverURL => {
244
- // 如果用户在 init 之后设置了 APIServerURL,保持用户设置
245
- if ( AVConfig . APIServerURL === API_HOST [ region ] ) {
246
- AVConfig . APIServerURL = `https://${ serverURL } ` ;
247
- }
248
- } ) ;
249
- }
253
+ AV . _config . region = region ;
254
+ AV . _config . APIServerURL = API_HOST [ region ] ;
255
+
256
+ Cache . getAsync ( 'APIServerURL' ) . then ( ( serverURL ) => {
257
+ if ( serverURL ) {
258
+ setServerUrl ( serverURL ) ;
259
+ getServerURLPromise . resolve ( ) ;
260
+ } else {
261
+ refreshServerUrl ( ) . then ( ( ) => {
262
+ getServerURLPromise . resolve ( ) ;
263
+ } ) ;
264
+ }
265
+ } ) ;
250
266
} ;
251
267
252
268
/**
@@ -266,16 +282,18 @@ const AVRequest = (route, className, objectId, method, dataObject = {}, sessionT
266
282
}
267
283
268
284
checkRouter ( route ) ;
269
- const apiURL = createApiUrl ( route , className , objectId , method , dataObject ) ;
270
285
271
- return setHeaders ( sessionToken ) . then (
272
- headers => ajax ( method , apiURL , dataObject , headers )
273
- . then (
274
- null ,
275
- res => handleError ( res )
276
- . then ( location => ajax ( method , location , dataObject , headers ) )
277
- )
278
- ) ;
286
+ return getServerURLPromise . always ( ( ) => {
287
+ const apiURL = createApiUrl ( route , className , objectId , method , dataObject ) ;
288
+ return setHeaders ( sessionToken ) . then (
289
+ headers => ajax ( method , apiURL , dataObject , headers )
290
+ . then (
291
+ null ,
292
+ res => handleError ( res )
293
+ . then ( location => ajax ( method , location , dataObject , headers ) )
294
+ )
295
+ ) ;
296
+ } ) ;
279
297
} ;
280
298
281
299
module . exports = {
0 commit comments