@@ -54,6 +54,16 @@ if (typeof XDomainRequest !== 'undefined' && !('withCredentials' in new XMLHttpR
5454 useXDomainRequest = true ;
5555}
5656
57+ function getPath ( base : string , pathname : string ) {
58+ if ( base . endsWith ( '/' ) ) {
59+ base = base . slice ( 0 , - 1 ) ;
60+ }
61+ if ( ! pathname . startsWith ( '/' ) ) {
62+ pathname = '/' + pathname ;
63+ }
64+ return base + pathname ;
65+ }
66+
5767function ajaxIE9 ( method : string , url : string , data : any , _headers ?: any , options ?: FullOptions ) {
5868 return new Promise ( ( resolve , reject ) => {
5969 // @ts -ignore
@@ -140,6 +150,7 @@ const RESTController = {
140150 method,
141151 headers,
142152 signal,
153+ redirect : 'manual' ,
143154 } ;
144155 if ( data ) {
145156 fetchOptions . body = data ;
@@ -189,6 +200,14 @@ const RESTController = {
189200 } else if ( status >= 400 && status < 500 ) {
190201 const error = await response . json ( ) ;
191202 promise . reject ( error ) ;
203+ } else if ( [ 301 , 302 , 303 , 307 , 308 ] . includes ( status ) ) {
204+ const location = response . headers . get ( 'location' ) ;
205+ promise . resolve ( {
206+ status,
207+ location,
208+ method : status === 303 ? 'GET' : method ,
209+ dropBody : status === 303 ,
210+ } ) ;
192211 } else if ( status >= 500 || status === 0 ) {
193212 // retry on 5XX or library error
194213 if ( ++ attempts < CoreManager . get ( 'REQUEST_ATTEMPT_LIMIT' ) ) {
@@ -221,12 +240,7 @@ const RESTController = {
221240
222241 request ( method : string , path : string , data : any , options ?: RequestOptions ) {
223242 options = options || { } ;
224- let url = CoreManager . get ( 'SERVER_URL' ) ;
225- if ( url [ url . length - 1 ] !== '/' ) {
226- url += '/' ;
227- }
228- url += path ;
229-
243+ const url = getPath ( CoreManager . get ( 'SERVER_URL' ) , path ) ;
230244 const payload : Partial < PayloadType > = { } ;
231245 if ( data && typeof data === 'object' ) {
232246 for ( const k in data ) {
@@ -302,15 +316,31 @@ const RESTController = {
302316 }
303317
304318 const payloadString = JSON . stringify ( payload ) ;
305- return RESTController . ajax ( method , url , payloadString , { } , options ) . then (
306- ( { response, status, headers } ) => {
307- if ( options . returnStatus ) {
308- return { ...response , _status : status , _headers : headers } ;
309- } else {
310- return response ;
319+ return RESTController . ajax ( method , url , payloadString , { } , options ) . then ( async ( result ) => {
320+ if ( result . location ) {
321+ let newURL = getPath ( result . location , path ) ;
322+ let newMethod = result . method ;
323+ let newBody = result . dropBody ? undefined : payloadString ;
324+
325+ // Follow up to 5 redirects to avoid loops
326+ for ( let i = 0 ; i < 5 ; i += 1 ) {
327+ const r = await RESTController . ajax ( newMethod , newURL , newBody , { } , options ) ;
328+ if ( ! r . location ) {
329+ result = r ;
330+ break ;
331+ }
332+ newURL = getPath ( r . location , path ) ;
333+ newMethod = r . method ;
334+ newBody = r . dropBody ? undefined : payloadString ;
311335 }
312336 }
313- ) ;
337+ const { response, status, headers } = result ;
338+ if ( options . returnStatus ) {
339+ return { ...response , _status : status , _headers : headers } ;
340+ } else {
341+ return response ;
342+ }
343+ } ) ;
314344 } )
315345 . catch ( RESTController . handleError ) ;
316346 } ,
0 commit comments