Bug 289294

Summary: Calling history.back() in an iframe stops all pending network requests
Product: WebKit Reporter: Ben Nham <nham>
Component: HistoryAssignee: Ben Nham <nham>
Status: RESOLVED FIXED    
Severity: Normal CC: paroga, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   

Ben Nham
Reported 2025-03-06 15:45:44 PST
Follow these steps: 1. Go to https://nham.me/misc/iframefetch/ 2. Click on "Navigate to Hash" 3. Click on "Start Fetch" 4. Click "Go Back" Notice that the fetch immediately terminates. The reason for this is that we sometimes eagerly stop all pending network requests when navigating history. In`Page::goToItem`, we are doing that here: if (frame.loader().protectedHistory()->shouldStopLoadingForHistoryItem(item)) frame.protectedLoader()->stopAllLoadersAndCheckCompleteness(); `HistoryController::shouldStopLoadingForHistoryItem` asks `HistoryItem::shouldDoSameDocumentNavigationTo` whether or not the navigation is same-document. If it's a cross-doc navigation, we eagerly stop all outstanding loaders. And here is the very first line of `HistoryItem::shouldDoSameDocumentNavigationTo` is if (m_itemID == otherItem.itemID()) return false; So navigating to a history item with the same ID is actually considered a *cross-document* navigation, which then stops all pending network requests. That's what's happening here: 1. We navigate to a fragment in the iframe, it modifies the history item further down the history tree, but the root history item's ID is unchanged. 2. When we call history.back(), that calls `Page::goToItem` with the old root history item, which has the same ID as the current root history item. So this is considered a cross-doc navigation. It looks like this behavior was added back in 2010 in bug 35532 (http://commits.webkit.org/r55375): > Telling a Page/FrameLoader to go to the same HistoryItem that is its current HistoryItem is supposed to effectively reload the page. creating a new load and new document. Note in particular the `item != currentItem` addition to FrameLoader.cpp, which eventually made its way to `HistoryController::shouldStopLoadingForHistoryItem` after refactoring. It's not clear what the best solution here is: - We could possibly remove the `m_itemID == otherItem.itemID()` logic from `shouldStopLoadingForHistoryItem`. - We could also possibly just remove this whole eager FrameLoader stopping logic entirely and count on some other logic to stop the FrameLoader when a new navigation commits in a frame. Maybe the call to stopAllLoaders in FrameLoader::continueLoadAfterNavigationPolicy already takes care of this?
Attachments
Radar WebKit Bug Importer
Comment 1 2025-03-06 15:48:02 PST
Ben Nham
Comment 2 2025-03-06 16:11:04 PST
*** Bug 22165 has been marked as a duplicate of this bug. ***
Ben Nham
Comment 3 2025-03-06 16:39:10 PST
EWS
Comment 4 2025-03-07 19:45:16 PST
Committed 291823@main (c71c8ea9721a): <https://commits.webkit.org/291823@main> Reviewed commits have been landed. Closing PR #42050 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.