@@ -76,6 +76,13 @@ export function supportsFetch(): boolean {
7676 return false ;
7777 }
7878}
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+
7986
8087/**
8188 * Tells whether current environment supports Fetch API natively
@@ -88,30 +95,31 @@ export function supportsNativeFetch(): boolean {
8895 return false ;
8996 }
9097
91- const isNativeFunc = ( func : Function ) => func . toString ( ) . indexOf ( 'native' ) !== - 1 ;
9298 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 ;
94108 const doc = global . document ;
95109 if ( doc ) {
96110 const sandbox = doc . createElement ( 'iframe' ) ;
97111 sandbox . hidden = true ;
98112 try {
99113 doc . head . appendChild ( sandbox ) ;
100114 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 ) ;
103116 }
104117 doc . head . removeChild ( sandbox ) ;
105118 } catch ( err ) {
106119 logger . warn ( 'Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ' , err ) ;
107120 }
108121 }
109122
110- if ( result === null ) {
111- // tslint:disable-next-line no-unbound-method
112- result = isNativeFunc ( global . fetch ) ;
113- }
114-
115123 return result ;
116124}
117125
0 commit comments