zoukankan      html  css  js  c++  java
  • 路由的基础理解【转】

    定义:路由是用来把请求映射到路由处理程序。应用程序一启动就配置了路由,并且可以从URL中提取值用于处理请求。它还负责使用 ASP.NET 应用程序中定义的路由来生成链接。

    路由使用 routes 类 ( iRouter 的实现) 做到:

    • 映射传入的请求到 路由处理程序
    • 生成响应中使用的 URLs

    1. 服务器端路由

    对于服务器来说,当接收到客户端发来的HTTP请求,会根据请求的URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有URL的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理,等等。

    以Express为例,

    app.get('/', (req, res) => {
      res.sendFile('index')
    })
    
    app.get('/users', (req, res) => {
      db.queryAllUsers()
        .then(data => res.send(data))
    })
    

    这里定义了两条路由:

    • 当访问/的时候,会返回index页面
    • 当访问/users的时候,会从数据库中取出所有用户数据并返回

    不仅仅是URL

    在router匹配route的过程中,不仅会根据URL来匹配,还会根据请求的方法来看是否匹配。例如上面的例子,如果通过POST方法来访问/users,就会找不到正确的路由。

    2. 客户端路由

    对于客户端(通常为浏览器)来说,路由的映射函数通常是进行一些DOM的显示和隐藏操作。这样,当访问不同的路径的时候,会显示不同的页面组件。客户端路由最常见的有以下两种实现方案:

    • 基于Hash
    • 基于History API

    (1) 基于Hash

    我们知道,URL中#及其后面的部分为hash。例如:

    const url = require('url')
    var a = url.parse('http://example.com/a/b/#/foo/bar')
    console.log(a.hash)
    // => #/foo/bar
    

    hash仅仅是客户端的一个状态,也就是说,当向服务器发请求的时候,hash部分并不会发过去。

    通过监听window对象的hashChange事件,可以实现简单的路由。例如:

    window.onhashchange = function() {
      var hash = window.location.hash
      var path = hash.substring(1)
    
      switch (path) {
        case '/':
          showHome()
          break
        case '/users':
          showUsersList()
          break
        default:
          show404NotFound()
      }
    }
    

    (2) 基于History API

    通过HTML5 History API可以在不刷新页面的情况下,直接改变当前URL。详细用法可以参考:

    Manipulating the browser history
    Using the HTML5 History API
    我们可以通过监听window对象的popstate事件,来实现简单的路由:

    window.onpopstate = function() {
      var path = window.location.pathname
    
      switch (path) {
        case '/':
          showHome()
          break
        case '/users':
          showUsersList()
          break
        default:
          show404NotFound()
      }
    }
    

    但是这种方法只能捕获前进或后退事件,无法捕获pushState和replaceState,一种最简单的解决方法是替换pushState方法,例如:

    var pushState = history.pushState
    history.pushState = function() {
      pushState.apply(history, arguments)
    
      // emit a event or just run a callback
      emitEventOrRunCallback()
    }
    

    不过,最好的方法还是使用实现好的history库。

    (3) 两种实现的比较

    总的来说,基于Hash的路由,兼容性更好;基于History API的路由,更加直观和正式。

    但是,有一点很大的区别是,基于Hash的路由不需要对服务器做改动,基于History API的路由需要对服务器做一些改造。下面来详细分析。

    假设服务器只有如下文件(script.js被index.html所引用):

    /-
     |- index.html
     |- script.js
    

    基于Hash的路径有:

    http://example.com/
    http://example.com/#/foobar
    

    基于History API的路径有:

    http://example.com/
    http://example.com/foobar
    

    当直接访问http://example.com/的时候,两者的行为是一致的,都是返回了index.html文件。

    当从http://example.com/跳转到http://example.com/#/foobar或者http://example.com/foobar的时候,也都是正常的,因为此时已经加载了页面以及脚本文件,所以路由跳转正常。

    当直接访问http://example.com/#/foobar的时候,实际上向服务器发起的请求是http://example.com/,因此会首先加载页面及脚本文件,接下来脚本执行路由跳转,一切正常。

    当直接访问http://example.com/foobar的时候,实际上向服务器发起的请求也是http://example.com/foobar,然而服务器端只能匹配/而无法匹配/foobar,因此会出现404错误。

    因此如果使用了基于History API的路由,需要改造服务器端,使得访问/foobar的时候也能返回index.html文件,这样当浏览器加载了页面及脚本之后,就能进行路由跳转了。

     

  • 相关阅读:
    SharePoint 2010 User Profile Sync Service自动停止
    如何区别多个svchost.exe?
    Log Parser分析IIS log的一个简单例子
    Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
    Windows中右键点击文件夹, 结果找不到共享选项卡, 怎么办?
    介绍SOS中的SaveModule命令
    SharePoint中Draft版本的文档不会收到document added的Alert Email
    和我一起学Windows Workflow Foundation(1)创建和调试一个WF实例
    门户网站
    C#基础—— check、lock、using语句归纳
  • 原文地址:https://www.cnblogs.com/zx0309/p/10519740.html
Copyright © 2011-2022 走看看