history 和 hash 区别:
1. hash 路由在地址栏URL上有"#",用 window.location.hash 读取。而 history 路由没有;
2. 在进行回车刷新操作时, hash 路由会加载到地址栏对应的页面,而 history 路由一般会出现404错误(刷新是网络请求,没有后端准备会报错);
3. hash 路由支持一些低版本的浏览器,而 history 路由不支持(是HTML5新增的API)。
4. hash 的特点在于它虽然出现在URL中,但是不包括在http请求中(hash值变化不会导致浏览器向服务器发出请求,而且 hash 改变会触发 hashChange 事件(hashChange只能改变#后面的url片段)),对后端是完全没有影响,所以改变 hash 不会重新加载页面,这也是单页面应用的必备。
5. history 运用了浏览器的历史记录栈,之前有 back, forward, go 方法, 之后在HTML5中新增了 pushState() 和 replaceState() 方法,它们提供了对历史记录进行修改的功能,不过在进行修改时,虽然改变了当前的URL,但是浏览器不会马上向后端发送请求。
6. history 的这种模式需要后端配置支持。比如:当我们进入项目主页的时候,一切正常,可以访问,但当我们刷新页面或者直接访问路径时就会返回404, 那是因为在 history 模式下,只是动态的通过 js 操作 window.history 来改变浏览器地址栏里的路径,并没有发起http请求,但是当我直接在浏览器里输入这个地址时,就一定要对服务器发起http请求,但是这个目标在服务器上又不存在,所以会返回404。
原理:
1. hash模式: 通过监听浏览器的 onhashchange()事件变化,查找对应的路由规则。
2. history模式: 利用HTML5的 history 中新增的两个API pushState() 和 replaceState() 和一个事件 onpopstate 监听URL变化。
总结:
history模式URL就要和后端保持一致,所以要改为history也需要后端的配合,否则会报错。
所以 hash 模式在每次刷新页面时是直接修改"#"后面的片段, history 模式每次刷新会重新向后端请求整个网址,也就是重新请求服务器。如果后端没有及时响应,就会报错404。
history 的好处是可以进行修改历史记录,并且不会立刻向后端发起请求。
出现404错误的解决办法:安装URL重写模块,配置重写规则,统一指向index.html或者直接把url重写生成的web.config文件直接放置到网站根目录下。