@@ -76,6 +76,13 @@ export function supportsFetch(): boolean {
76
76
return false ;
77
77
}
78
78
}
79
+ /**
80
+ * isNativeFetch checks if the given function is a native implementation of fetch()
81
+ */
82
+ function isNativeFetch ( func : Function ) : boolean {
83
+ return func && / ^ f u n c t i o n f e t c h \( \) \s + \{ \s + \[ n a t i v e c o d e \] \s + \} $ / . test ( func . toString ( ) ) ;
84
+ }
85
+
79
86
80
87
/**
81
88
* Tells whether current environment supports Fetch API natively
@@ -88,30 +95,31 @@ export function supportsNativeFetch(): boolean {
88
95
return false ;
89
96
}
90
97
91
- const isNativeFunc = ( func : Function ) => func . toString ( ) . indexOf ( 'native' ) !== - 1 ;
92
98
const global = getGlobalObject < Window > ( ) ;
93
- let result = null ;
99
+
100
+ // Fast path to avoid DOM I/O
101
+ if ( isNativeFetch ( global . fetch ) ) {
102
+ return true ;
103
+ }
104
+
105
+ // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)
106
+ // so create a "pure" iframe to see if that has native fetch
107
+ let result = false ;
94
108
const doc = global . document ;
95
109
if ( doc ) {
96
110
const sandbox = doc . createElement ( 'iframe' ) ;
97
111
sandbox . hidden = true ;
98
112
try {
99
113
doc . head . appendChild ( sandbox ) ;
100
114
if ( sandbox . contentWindow && sandbox . contentWindow . fetch ) {
101
- // tslint:disable-next-line no-unbound-method
102
- result = isNativeFunc ( sandbox . contentWindow . fetch ) ;
115
+ result = isNativeFetch ( sandbox . contentWindow . fetch ) ;
103
116
}
104
117
doc . head . removeChild ( sandbox ) ;
105
118
} catch ( err ) {
106
119
logger . warn ( 'Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ' , err ) ;
107
120
}
108
121
}
109
122
110
- if ( result === null ) {
111
- // tslint:disable-next-line no-unbound-method
112
- result = isNativeFunc ( global . fetch ) ;
113
- }
114
-
115
123
return result ;
116
124
}
117
125
0 commit comments