66const request = require ( 'superagent' ) ;
77const debug = require ( 'debug' ) ( 'request' ) ;
88const md5 = require ( 'md5' ) ;
9- const Promise = require ( './promise' ) ;
9+ const AVPromise = require ( './promise' ) ;
1010const Cache = require ( './cache' ) ;
1111const AVError = require ( './error' ) ;
1212const 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+ } ;
1322
1423// 计算 X-LC-Sign 的签名方法
1524const sign = ( key , isMasterKey ) => {
@@ -65,7 +74,7 @@ const checkRouter = (router) => {
6574const ajax = ( method , resourceUrl , data , headers = { } , onprogress ) => {
6675 debug ( method , resourceUrl , data , headers ) ;
6776
68- const promise = new Promise ( ) ;
77+ const promise = new AVPromise ( ) ;
6978 const req = request ( method , resourceUrl )
7079 . set ( headers )
7180 . send ( data )
@@ -109,7 +118,7 @@ const setHeaders = (sessionToken) => {
109118 headers [ 'User-Agent' ] = AV . _config . userAgent || `AV/${ AV . version } ; Node.js/${ process . version } ` ;
110119 }
111120
112- const promise = new Promise ( ) ;
121+ const promise = new AVPromise ( ) ;
113122
114123 // Pass the session token
115124 if ( sessionToken ) {
@@ -179,20 +188,23 @@ const cacheServerURL = (serverURL, ttl) => {
179188 if ( typeof ttl !== 'number' ) {
180189 ttl = 3600 ;
181190 }
182- Cache . set ( 'APIServerURL' , serverURL , ttl * 1000 ) ;
191+ return Cache . setAsync ( 'APIServerURL' , serverURL , ttl * 1000 ) ;
183192} ;
184193
185194// handle AV._request Error
186195const handleError = ( res ) => {
187- const promise = new Promise ( ) ;
196+ const promise = new AVPromise ( ) ;
188197 /**
189198 When API request need to redirect to the right location,
190199 can't use browser redirect by http status 307, as the reason of CORS,
191200 so API server response http status 410 and the param "location" for this case.
192201 */
193202 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+ } ) ;
196208 } else {
197209 let errorJSON = { code : - 1 , error : res . responseText } ;
198210 if ( res . response && res . response . code ) {
@@ -213,40 +225,44 @@ const handleError = (res) => {
213225 return promise ;
214226} ;
215227
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 } ` ;
222230
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' ) => {
225249 // 如果用户在 init 之前设置了 APIServerURL,则跳过请求 router
226- if ( AVConfig . APIServerURL ) {
250+ if ( AV . _config . APIServerURL ) {
227251 return ;
228252 }
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+ } ) ;
250266} ;
251267
252268/**
@@ -266,16 +282,18 @@ const AVRequest = (route, className, objectId, method, dataObject = {}, sessionT
266282 }
267283
268284 checkRouter ( route ) ;
269- const apiURL = createApiUrl ( route , className , objectId , method , dataObject ) ;
270285
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+ } ) ;
279297} ;
280298
281299module . exports = {
0 commit comments