Search code examples
javascriptc#.netnavigation.net-4.8

How to Avoid Page_Load When Users Arrive at Certain Pages Using Browser Back/Forward Buttons


I want to redirect the user to another page anytime they arrived certain pages by clicking on back/forward buttons of the browser. I've found a JavaScript solution as shown below. (This is a simplified example without mapping what URL to be redirected to.)

if(is_safe(window.location.href))
    return;
if (window.performance.getEntriesByType("navigation")[0].type === "back_forward")
    window.location.href = "/Home.aspx";

That works fine, except it happens client-side, which is after Page_Load. I want to avoid the entire Page_Load event, or at least be able to run only part of it if user arrives certain pages, because many pages has Page_Load event that actually post database changes (I know... This is bad). Also, even if that is not the case, it'll be nice to avoid loading data when the user will be redirected to another page anyway.

How to achieve this goal?


EDIT: I didn't redirect or detect the navigation type from source when they click on the back button because it is either impossible or very inconsistent. At some point when I haven't figure out this JavaScript solution, I've even tried to redirect the user twice, but wouldn't work because browsers skips the redirect and post when back button clicked. If redirecting or detecting from source is possible, I would be more than happy to be corrected! The PRG pattern is complied to avoid double submit, but I don't think it's relevant here.


Solution

  • I figured history.replaceState() is enough to achieve the goal (If user arrives certain pages by back/forward buttons, avoid Page_Load events). The key here is that modifying the URL of the current state using replaceState won't cause the page to reload based on the new URL. (This is intended, as the purpose of this method is to rewrite the document's attached URL to a target URL.) If placed in events such as onbeforeunload, the user will not see the URL being modified.

    However, a big limitation of this approach is that if a user clicked on refresh, it will load the page based on the replaced URL. Since clicking on refresh counts as a postback, which can be detected by !Page.IsPostBack in Page_Load, this action could be allowed. This method sacrifices the ability to enable users to click on refresh and stay on the same page for those pages where the URL was modified.

    window.onbeforeunload = function () {
      const unsafePages = {
        "/pages/unsafeOperation": "/pages/unsafeOperationList"
      }
      const currentPath = location.pathname;
      if (currentPath in unsafePages)
        history.replaceState({id: `${currentPath} replaced`}, "", unsafePages[currentPath]);
    }