@@ -348,7 +348,7 @@ function normalizeMethod(method) {
348348 return methods . indexOf ( upcased ) > - 1 ? upcased : method
349349}
350350
351- export function Request ( input , options ) {
351+ export function Request ( input , options , xhr ) {
352352 if ( ! ( this instanceof Request ) ) {
353353 throw new TypeError ( 'Please use the "new" operator, this DOM object constructor cannot be called as a function.' )
354354 }
@@ -393,7 +393,7 @@ export function Request(input, options) {
393393 if ( ( this . method === 'GET' || this . method === 'HEAD' ) && body ) {
394394 throw new TypeError ( 'Body not allowed for GET or HEAD requests' )
395395 }
396- this . _initBody ( body , options )
396+ this . _initBody ( body , options , xhr )
397397
398398 if ( this . method === 'GET' || this . method === 'HEAD' ) {
399399 if ( options . cache === 'no-store' || options . cache === 'no-cache' ) {
@@ -461,7 +461,7 @@ function parseHeaders(rawHeaders) {
461461
462462Body . call ( Request . prototype )
463463
464- export function Response ( bodyInit , options ) {
464+ export function Response ( bodyInit , options , xhr ) {
465465 if ( ! ( this instanceof Response ) ) {
466466 throw new TypeError ( 'Please use the "new" operator, this DOM object constructor cannot be called as a function.' )
467467 }
@@ -478,7 +478,7 @@ export function Response(bodyInit, options) {
478478 this . statusText = options . statusText === undefined ? '' : '' + options . statusText
479479 this . headers = new Headers ( options . headers )
480480 this . url = options . url || ''
481- this . _initBody ( bodyInit , options )
481+ this . _initBody ( bodyInit , options , xhr )
482482}
483483
484484Body . call ( Response . prototype )
@@ -526,14 +526,14 @@ try {
526526
527527export function fetch ( input , init ) {
528528 return new Promise ( function ( resolve , reject ) {
529- var request = new Request ( input , init )
529+ var xhr = new XMLHttpRequest ( )
530+ var sent = false
531+ var request = new Request ( input , init , xhr )
530532
531533 if ( request . signal && request . signal . aborted ) {
532534 return reject ( new DOMException ( 'Aborted' , 'AbortError' ) )
533535 }
534536
535- var xhr = new XMLHttpRequest ( )
536-
537537 function abortXhr ( ) {
538538 xhr . abort ( )
539539 }
@@ -553,7 +553,9 @@ export function fetch(input, init) {
553553 options . url = 'responseURL' in xhr ? xhr . responseURL : options . headers . get ( 'X-Request-URL' )
554554 var body = 'response' in xhr ? xhr . response : xhr . responseText
555555 setTimeout ( function ( ) {
556- resolve ( new Response ( body , options ) )
556+ if ( sent ) return
557+ sent = true
558+ resolve ( new Response ( body , options , xhr ) )
557559 } , 0 )
558560 }
559561
@@ -575,10 +577,6 @@ export function fetch(input, init) {
575577 } , 0 )
576578 }
577579
578- if ( init ?. onxhr ) {
579- init . onxhr ( xhr )
580- }
581-
582580 function fixUrl ( url ) {
583581 try {
584582 return url === '' && g . location . href ? g . location . href : url
@@ -633,6 +631,26 @@ export function fetch(input, init) {
633631 }
634632 }
635633
634+ // XXX(@jwerle): introduced to support 'text/event-stream' or any other streaming text sources
635+ xhr . addEventListener ( 'progress' , ( ) => {
636+ if ( sent ) return
637+ var options = {
638+ statusText : xhr . statusText ,
639+ headers : parseHeaders ( xhr . getAllResponseHeaders ( ) || '' ) ,
640+ status : xhr . status ,
641+ url : ''
642+ }
643+ if ( ( options . headers . get ( 'content-type' ) || '' ) . startsWith ( 'text/' ) ) {
644+ options . url = 'responseURL' in xhr ? xhr . responseURL : options . headers . get ( 'X-Request-URL' )
645+ sent = true
646+ resolve ( new Response ( null , options , xhr ) )
647+ }
648+ } , { once : true } )
649+
650+ if ( init ?. onxhr ) {
651+ init . onxhr ( xhr )
652+ }
653+
636654 xhr . send ( typeof request . _bodyInit === 'undefined' ? null : request . _bodyInit )
637655 } )
638656}
0 commit comments