Browse Source

Fix XMLHttpRequest auto strategy

Ben Hsieh 7 years ago
parent
commit
b2f47bb657
3 changed files with 53 additions and 27 deletions
  1. 19
    2
      src/index.js
  2. 26
    21
      src/ios/RNFetchBlobNetwork.m
  3. 8
    4
      src/polyfill/XMLHttpRequest.js

+ 19
- 2
src/index.js View File

@@ -254,14 +254,31 @@ class FetchBlobResponse {
254 254
      * @return {string} Decoded base64 string.
255 255
      */
256 256
     this.text = ():string => {
257
-      return decodeURIComponent(base64.decode(this.data))
257
+      let res = this.data
258
+      try {
259
+        res = base64.decode(this.data)
260
+        res = decodeURIComponent(res)
261
+      } catch(err) {
262
+        console.warn(err)
263
+        res = ''
264
+      }
265
+      return res
258 266
     }
259 267
     /**
260 268
      * Convert result to JSON object.
261 269
      * @return {object} Parsed javascript object.
262 270
      */
263 271
     this.json = ():any => {
264
-      return JSON.parse(decodeURIComponent(base64.decode(this.data)))
272
+      let res = this.data
273
+      try {
274
+        res = base64.decode(this.data)
275
+        res = decodeURIComponent(res)
276
+        res = JSON.parse(res)
277
+      } catch(err) {
278
+        console.warn(err)
279
+        res = {}
280
+      }
281
+      return res
265 282
     }
266 283
     /**
267 284
      * Return BASE64 string directly.

+ 26
- 21
src/ios/RNFetchBlobNetwork.m View File

@@ -137,9 +137,11 @@ NSOperationQueue *taskQueue;
137 137
 
138 138
     
139 139
     NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
140
-    if([options valueForKey:@"timeout"] != nil)
140
+    float timeout = [options valueForKey:@"timeout"] == nil ? -1 : [[options valueForKey:@"timeout"] floatValue];
141
+    NSLog(@"timeout = %f",timeout);
142
+    if(timeout > 0)
141 143
     {
142
-        defaultConfigObject.timeoutIntervalForRequest = [[options valueForKey:@"timeout"] floatValue]/1000;
144
+        defaultConfigObject.timeoutIntervalForRequest = timeout/1000;
143 145
     }
144 146
     defaultConfigObject.HTTPMaximumConnectionsPerHost = 10;
145 147
     session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:taskQueue];
@@ -196,21 +198,30 @@ NSOperationQueue *taskQueue;
196 198
  
197 199
     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
198 200
     NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
201
+    NSString * respType = @"";
199 202
     respStatus = statusCode;
200 203
     if ([response respondsToSelector:@selector(allHeaderFields)])
201 204
     {
202 205
         NSDictionary *headers = [httpResponse allHeaderFields];
203
-        NSString * respType = [[RNFetchBlobReqBuilder getHeaderIgnoreCases:@"content-type"
206
+        NSString * respCType = [[RNFetchBlobReqBuilder getHeaderIgnoreCases:@"Content-Type"
204 207
                                                                fromHeaders:headers]
205 208
                                lowercaseString];
206
-        if([headers valueForKey:@"Content-Type"] != nil)
209
+        if(respCType != nil)
207 210
         {
208 211
             NSArray * extraBlobCTypes = [options objectForKey:CONFIG_EXTRA_BLOB_CTYPE];
212
+            if([respCType containsString:@"text/"])
213
+            {
214
+                respType = @"text";
215
+            }
216
+            else if([respCType containsString:@"application/json"])
217
+            {
218
+                respType = @"json";
219
+            }
209 220
             // If extra blob content type is not empty, check if response type matches
210
-            if( extraBlobCTypes !=  nil) {
221
+            else if( extraBlobCTypes !=  nil) {
211 222
                 for(NSString * substr in extraBlobCTypes)
212 223
                 {
213
-                    if([[respType lowercaseString] containsString:[substr lowercaseString]])
224
+                    if([respCType containsString:[substr lowercaseString]])
214 225
                     {
215 226
                         respType = @"blob";
216 227
                         respFile = YES;
@@ -219,14 +230,6 @@ NSOperationQueue *taskQueue;
219 230
                     }
220 231
                 }
221 232
             }
222
-            else if([respType containsString:@"text/"])
223
-            {
224
-                respType = @"text";
225
-            }
226
-            else if([respType containsString:@"application/json"])
227
-            {
228
-                respType = @"json";
229
-            }
230 233
             else
231 234
             {
232 235
                 respType = @"blob";
@@ -238,7 +241,7 @@ NSOperationQueue *taskQueue;
238 241
             }
239 242
         }
240 243
         else
241
-            respType = @"";
244
+            respType = @"text";
242 245
         respInfo = @{
243 246
                      @"taskId": taskId,
244 247
                      @"state": @"2",
@@ -255,6 +258,8 @@ NSOperationQueue *taskQueue;
255 258
         headers = nil;
256 259
         respInfo = nil;
257 260
     }
261
+    else
262
+        NSLog(@"oops");
258 263
 
259 264
     if(respFile == YES)
260 265
     {
@@ -319,20 +324,20 @@ NSOperationQueue *taskQueue;
319 324
     self.error = error;
320 325
     NSString * errMsg = [NSNull null];
321 326
     NSString * respStr = [NSNull null];
322
-    NSString * respType = [respInfo valueForKey:@"respType"];
323 327
     
324 328
     [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
325
-    if(error != nil)
326
-    {
327
-        errMsg = [error localizedDescription];
328
-    }
329
+    
329 330
     if(respInfo == nil)
330 331
     {
331 332
         respInfo = [NSNull null];
332 333
     }
333 334
     
335
+    if(error != nil)
336
+    {
337
+        errMsg = [error localizedDescription];
338
+    }
334 339
     // Fix #72 response with status code 200 ~ 299 considered as success
335
-    if(respStatus> 299 || respStatus < 200)
340
+    else if(respStatus> 299 || respStatus < 200)
336 341
     {
337 342
         errMsg = [NSString stringWithFormat:@"Request failed, status %d", respStatus];
338 343
     }

+ 8
- 4
src/polyfill/XMLHttpRequest.js View File

@@ -23,7 +23,9 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
23 23
   _onreadystatechange : () => void;
24 24
 
25 25
   upload : XMLHttpRequestEventTarget = new XMLHttpRequestEventTarget();
26
-  static binaryContentTypes : Array<string> = [];
26
+  static binaryContentTypes : Array<string> = [
27
+    'image/', 'video/', 'audio/'
28
+  ];
27 29
 
28 30
   // readonly
29 31
   _readyState : number = UNSENT;
@@ -145,7 +147,6 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
145 147
     }
146 148
     else
147 149
       body = body ? body.toString() : body
148
-
149 150
     this._task = RNFetchBlob
150 151
                   .config({
151 152
                     auto: true,
@@ -243,7 +244,6 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
243 244
   }
244 245
 
245 246
   _uploadProgressEvent(send:number, total:number) {
246
-    console.log('_upload', this.upload)
247 247
     if(!this._uploadStarted) {
248 248
       this.upload.dispatchEvent('loadstart')
249 249
       this._uploadStarted = true
@@ -265,12 +265,16 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
265 265
   }
266 266
 
267 267
   _onError(err) {
268
+    let statusCode = Math.floor(this.status)
269
+    if(statusCode >= 100 && statusCode !== 408) {
270
+      return
271
+    }
268 272
     log.verbose('XMLHttpRequest error', err)
269 273
     this._statusText = err
270 274
     this._status = String(err).match(/\d+/)
271 275
     this._status = this._status ? Math.floor(this.status) : 404
272 276
     this._dispatchReadStateChange(XMLHttpRequest.DONE)
273
-    if(err && String(err.message).match(/(timed\sout|timedout)/)) {
277
+    if(err && String(err.message).match(/(timed\sout|timedout)/) || this._status == 408) {
274 278
       this.dispatchEvent('timeout')
275 279
     }
276 280
     this.dispatchEvent('loadend')