Detailed explanation of front-end routing hash mode and history mode

Insert image description here

Preface

In projects with separate front-end and back-end, the front-end generally uses the SPA single-page application model to develop the project. So, what is a spa?

A single page web application (SPA) is an application with only one web page. It is a web application that loads a single HTML page and dynamically updates the page when the user interacts with the application.

My understanding:A single-page application changes the URL address of the page. It does not send requests to the background, but dynamically renders page components through front-end routing and changes the URL address. It has nothing to do with the background.

Front-end routing is divided into two modes:

  1. hash pattern
  2. history mode

Comparison of the two modes:

Compared hash pattern history mode
url display URL with "#" There is no "#" in the url
Enter to refresh (browser refresh button) The page displays normally If the backend is not configured, the page displays 404
Supported version Supports lower version browsers and IE browsers HTML5 new API

The essence of front-end routing is to monitor changes in url addresses or hash values ​​to switch and render the corresponding page components.

Next let’s take a closer look at the two routing modes.

1. Hash mode

1. Hash definition

The hash mode is a mode that uses # to splice the front-end routing path behind the real url, and uses the hashchange event to listen for changes in the hash value to render the corresponding component of the page. Hash mode does not send http requests to the backend, and all hash value operations are independent of the backend.

Use location.hash to get the hash value.

url location: http://localhost:8080/#/about example:

Insert image description here

2. location object

location is a shorthand pattern for window.location or document.location.

Insert image description here

Let's take a look at some common properties of location:

URL location:http://localhost:8080/#/about?name=she&age=16 Example:

Attributes explain value
hash Set or return anchor information starting from # #/about?name=she&age=16
host Set or return hostname + port number localhost:8080
hostname Sets or returns the hostname localhost
port Set or return port number 8080
href Sets or returns the full URL http://localhost:8080/#/about?name=she&age=16
origin Set or return protocol+host+port http://localhost:8080
pathname Sets or returns the path of the current URL / (The hash value is not included in the path, what is returned here is the slash before #)
protocol Set or return the current protocol http:
search Sets or returns the query string starting with ? ?name=she&age=16

location common methods:

method name explain grammar
assign() Loads and displays the contents of the specified URL location.assign(url);
reload() Refresh the current page, just like the refresh button location.reload();
replace() Replaces the current resource with the given URL location.replace(url);

After callslocation.replace() method, the current page will not be saved to the session history (session History). In this way, the user clicks When you click the back button, you will no longer jump to this page.

Insert image description here

3. window.onhashchange event

The hashchange event is fired when the URL's fragment identifier (hash value) changes (the portion of the URL that follows the # symbol, including the # symbol).

  • Use addEventListener to listen to hashchange events:

    window.addEventListener('hashchange', function() {
          
          
      console.log('hash值被修改了')
    }, false);
    
  • Using onhashchange event handler

    function locationHashChanged() {
          
          
    	if (location.hash === '#/about') {
          
          
    		console.log("欢迎进入about页面");
    	}
    }
    window.onhashchange = locationHashChanged;
    

Test hashchage event:

window.addEventListener('hashchange', function () {
    
    
	console.log('hashchage 事件被触发了');
});
// hash值的改变也会触发 window.onpopstate事件,onpopstate事件在 history模式中再做介绍
window.addEventListener("popstate", () => {
    
    
	console.log("popstate 事件被触发了");
})

Insert image description here

Modify the browser URL address directly and add the hash value #/about. It can be seen that modifying the hash value will trigger the popstate event first, and then trigger the hashchange event:
Insert image description here

Retrieve the hash value:

Insert image description here

2. History mode

1. History definition

History is a new feature provided by HTML5 that allows developers to directly change the front-end routing, that is, change the url address without sending an http request to the back-end.

history is the shorthand pattern for window.history and is the instantiation object of the History constructor.

The History interface allows manipulation of the browser's session history that has been accessed in tabs or frames.

In other words, History stores the access records of all browsed pages of the current tab page.

2、history API

  1. Instantiate object properties

    Attributes explain value
    length The number of elements in the session history, including the currently loaded page Integer (integer value)
    scrollRestoration Set the browser's default scrolling behavior auto(default value, browser automatically scrolls) / manual(turn off browser automatic scrolling) )
    state Returns an arbitrary value representing the state at the top of the history stack any (any value)
  2. instantiate object method

    method name explain grammar
    back() Move back one page in session history. If there is no previous page, this method call does nothing window.history.back()
    forward() Move forward one page in session history window.history.forward();
    go() go method to load specific page from session history window.history.go(-1); Negative value means moving backward back(), positive value means moving forward forward(); Reload the current page when the value is 0 or not passed.
    pushState() Add a record to the current browser history history.pushState(state, title[, url])
    replaceState() Modifying the current history entity can update the state object and URL address. history.replaceState(stateObj, title[, url]);
  3. Use of history.pushState()

    The history.pushState() method receives three parameters:

    • state: an object. When the popState event is triggered, the state object will be passed into the callback function. If no parameters are required, set it to null.

    • title: The title of the new page, but all browsers currently ignore this value, so it can be set to an empty string "" or null.

    • url: The new URL must be in the same domain as the current page. The browser's address bar will display this URL.

      Let’s do a test next, there is a a.html page:
      Insert image description here

      Use the pushState method to add a record to the History session history and pass the parameters:
      Insert image description here
      After using pushState to add a record, the url address is updated, but the page is not updated, that is to say The pushState method only updates the url address .
      Use length and state to view:
      Insert image description here

  4. Use of history.replaceState()

    The parameters received by the history.replaceState() method are the same as the history.pushState() method.The only difference is that using replaceState will update the records of the current page, including the state object and URL address.

    For example, use pushState to add a.html b.html c.html three records, then use replaceState to add d.html, and finally check how many histories are included in the history stack Record:
    Insert image description here
    Insert image description here
    As can be seen from the above figure, there are only three records in the history stack, namely ["a.html", "b.html", "d.html"]. The reason is that replaceState replaces c.html with d.html.

    So using history.back() will return b.html.
    Insert image description here
    Using history.forward() will only display d.html:
    Insert image description here

3, window.onpopstate incident

The window.onpopstate event is used to monitor changes in browsing history.

Call history.pushState() or history.replaceState() will not trigger the popstate event. The popstate event will only be triggered under certain actions of the browser, such as clicking the forward and back buttons (or calling history.back(), history.forward(), < in JavaScript a i=5> method). That is, navigating between two history entries for the same document triggers this event. history.go()

  • Use addEventListener to listen to popstate events:

    window.addEventListener('popstate', function(event) {
          
          
      console.log(event);
    }, false);
    
  • Using onpopstate event handler

    function historyStateChanged(event) {
          
          
    	console.log(event);
    }
    window.onpopstate= historyStateChanged;
    

Test, use popstate to listen for changes in the recording stack:

window.addEventListener("popstate", (event) => {
    
    
	console.log(event);
})

Using pushState and replaceState does not trigger the popstate event:
Insert image description here

Use history.back() to trigger the popstate event and print the parameter event.As can be seen from the figure below, the state object is saved in the event event object< a i=2>.

Insert image description here

4. Solve the 404 problem of page refresh in history mode

Under history, you can freely modify the path, but when refreshing the page, if there is no corresponding response or resource in the server, a 404 page will appear, because refreshing the page will send an http request. In other words, when using the history routing mode, the server needs to be used to allow the address to be accessible, and the backend must also be configured with the current resource path address.

If nginx is used for background deployment, you can configure nginx as follows to solve the page refresh problem (excerpt):

server {
    
    
	listen	8080;
	server_name  localhost;
	location / {
    
    
	    root  'E:\dist';
	    index  /index.html;
	    try_files $uri $uri/ /index.html;
	}
}

Guess you like

Origin blog.csdn.net/ThisEqualThis/article/details/130385068