diff --git a/system/web/context/RequestContext.cfc b/system/web/context/RequestContext.cfc index 7d65176c5..962bc7d26 100644 --- a/system/web/context/RequestContext.cfc +++ b/system/web/context/RequestContext.cfc @@ -1926,7 +1926,18 @@ component serializable="false" accessors="true" { * Determines if in an Ajax call or not by looking at the request headers */ boolean function isAjax(){ - return ( getHTTPHeader( "X-Requested-With", "" ) eq "XMLHttpRequest" ); + var xRequestedWith = getHTTPHeader( "X-Requested-With", "" ); + var fetchMode = getHTTPHeader( "Sec-Fetch-Mode", "" ); + var fetchDest = getHTTPHeader( "Sec-Fetch-Dest", "" ); + + return ( + xRequestedWith eq "XMLHttpRequest" || + ( + len( fetchMode ) && + fetchMode neq "navigate" && + fetchDest eq "empty" + ) + ); } /***********************************************************************************************************/ diff --git a/tests/specs/web/context/RequestContextTest.cfc b/tests/specs/web/context/RequestContextTest.cfc index 1321af75b..b52004f1e 100755 --- a/tests/specs/web/context/RequestContextTest.cfc +++ b/tests/specs/web/context/RequestContextTest.cfc @@ -616,6 +616,45 @@ component extends="coldbox.system.testing.BaseModelTest" { assertTrue( isSimpleValue( test ) ); } + function testIsAjaxWithXMLHttpRequestHeader(){ + var event = getRequestContext() + .$( "getHTTPHeader" ) + .$args( "X-Requested-With", "" ) + .$results( "XMLHttpRequest" ); + + expect( event.isAjax() ).toBeTrue(); + } + + function testIsAjaxWithFetchMetadataHeaders(){ + var event = getRequestContext() + .$( "getHTTPHeader" ) + .$args( "X-Requested-With", "" ) + .$results( "" ) + .$( "getHTTPHeader" ) + .$args( "Sec-Fetch-Mode", "" ) + .$results( "cors" ) + .$( "getHTTPHeader" ) + .$args( "Sec-Fetch-Dest", "" ) + .$results( "empty" ); + + expect( event.isAjax() ).toBeTrue(); + } + + function testIsAjaxFalseForNavigationRequests(){ + var event = getRequestContext() + .$( "getHTTPHeader" ) + .$args( "X-Requested-With", "" ) + .$results( "" ) + .$( "getHTTPHeader" ) + .$args( "Sec-Fetch-Mode", "" ) + .$results( "navigate" ) + .$( "getHTTPHeader" ) + .$args( "Sec-Fetch-Dest", "" ) + .$results( "document" ); + + expect( event.isAjax() ).toBeFalse(); + } + function testNoLayout(){ var event = getRequestContext();