DOM

BOM

事件

AJAX

存储

路由

客户端路由和后端路由的区别

1、客户端路由
不同的url地址对应到不同的内容或页面这个任务是由前端来完成的,就是前端路由,前端路由是不会刷新页面的。分为:
(1)hash模式
hash就是一段url中的#后面的内容,hash虽然包含在url中但是不被包括在http请求中,用来指导浏览器动作,对服务器端安全无用,改变hash不会加载页面(也正是因为#后面的内容不被包含在请求中,所以对于后端来说即便没有做到对路由的全覆盖也不会出现404)。因此可以通过Onhashchange来监听路由改变从而改变相应的页面内容(可以去做ajax请求)。

  1. window.addEventListener('hashchange', function() {
  2. console.log('The hash has changed!')
  3. }, false);

(2)history模式
html5新增了两个API,history.pushState()history.replaceState(),这两个API都会操作浏览器的历史记录堆栈,通过这种方式不会引起页面的刷新。但是这种情况下并没有向onhashchange那么好用的方法来监听url的改变,所以需要从三个角度去做控制。

  • 当点击了a标签进行页面跳转时,那么给a标签添加一个onClick事件,事件回调中先阻止a标签的默认跳转行为,通过event.target.href获取到url,就能根据映射关系去执行相应的回调了;
  • 脚本中直接调用history.pushState()history.replaceState()时(并不会触发onpopstate),也是通过url拿到映射的回调去执行;

    1. // 监听popState事件
    2. window.onpopstate = function(event){
    3. var state = event.state;
    4. routeMap[state.route].call(this);
    5. }
  • 点击浏览器的前进、后退按钮,这里需要另一个事件onpopstate,当浏览器历史记录被激活时触发,这个事件回调可以获取到当前的url,然后根据映射关系执行回调;

    1. function clickHandler (event){
    2. var route = event.target.href;
    3. history.pushState({route:route},null,route);
    4. routeMap[route].call(this);
    5. return false;
    6. }

因为history模式下url与向后端发起请求的url一致,所以需要服务器端支持(做到对路由的全覆盖),将所有的url请求都指向同一个html,否则没有配置的话刷新会报404。需要再nginx做路由的全覆盖配置

  1. server {
  2. listen 80;
  3. server_name localhost;
  4. root /usr/share/nginx/html;
  5. index index.html index.htm;
  6. location / {
  7. # 解决单页应用服务端路由的问题:把所有页面都重写到Index.html
  8. try_files $uri $uri/ /index.html;
  9. # 非带 hash 的资源,需要配置 Cache-Control: no-cache,避免浏览器默认为强缓存
  10. expires -1;
  11. }
  12. location /static {
  13. # 带 hash 的资源,需要配置长期缓存
  14. expires 1y;
  15. }
  16. }

2、后端路由
当在地址栏切换不同的ur时,都会向服务器发送一个请求,服务器响应这个请求,并在服务端拼接好html文件返回给页面来展示。