什么是web框架?web框架解读

  咱们经常使用的web前端框架其实简单称呼叫web框架,现阶段web前端技术成熟,从视觉体验到用户体验都是比较好的,这也是从简单到复杂的web前端框架技术实现的,在国内前端技术开发人员也是很是的多,市面上的前端框架能够说是眼花缭乱,这里写这篇文章就是让你在使用不一样的前端框架的时候可以明确的知道本身的选择。html

  

  Web前端框架工做原理:前端

  

  在咱们讨论框架以前,咱们须要理解 Web 如何“工做”的。为此,咱们将深刻挖掘你在浏览器里输入一个 URL 按下 Enter 以后都发生了什么。在你的浏览器中打开一个新的标签,浏览http://www.uileader.com。咱们讨论为了显示这个页面,浏览器都作了什么事情(不关心 DNS 查询)。程序员

  

  Web 服务器web

  

  每一个页面都以 HTML 的形式传送到你的浏览器中,HTML 是一种浏览器用来描述页面内容和结构的语言。那些负责发送 HTML 到浏览器的应用称之为“Web 服务器”,会让你迷惑的是,这些应用运行的机器一般也叫作 web 服务器。正则表达式

  

  然而,最重要的是要理解,到最后全部的 web 应用要作的事情就是发送 HTML 到浏览器。无论应用的逻辑多么复杂,最终的结果老是将 HTML 发送到浏览器(我故意将应用能够响应像 JSON 或者 CSS 等不一样类型的数据忽略掉,由于在概念上是相同的)。数据库

  

  HTTP编程

  

  浏览器从 web 服务器(或者叫应用服务器)上使用 HTTP 协议下载网站,HTTP 协议是基于一种 请求-响应(request-response)模型的。客户端(你的浏览器)从运行在物理机器上的 web 应用请求数据,web 应用反过来对你的浏览器请求进行响应。设计模式

  

  重要的一点是,要记住通讯老是由客户端(你的浏览器)发起的,服务器(也就是 web 服务器)没有办法建立一个连接,发送没有通过请求的数据给你的浏览器。若是你从 web 服务器上接收到数据,必定是由于你的浏览器显示地发送了请求。浏览器

  

  HTTP Methods缓存

  

  在 HTTP 协议中,每条报文都关联方法(method 或者 verb),不一样的 HTTP 方法对应客户端能够发送的逻辑上不一样类型的请求,反过来也表明了客户端的不一样意图。例如,请求一个 web 页面的 HTML,与提交一个表单在逻辑上是不一样的,因此这两种行为就须要使用不一样的方法。

  

  HTTP GET

  

  GET 方法就像其听起来的那样,从 web 服务器上 get(请求)数据。GET 请求是到目前位置最多见的一种 HTTP 请求,在一次 GET 请求过程当中,web 应用对请求页面的 HTML 进行响应以外,就不须要作任何事情了。特别的,web 应用在 GET 请求的结果中,不该该改变应用的状态(好比,不能基于 GET 请求建立一个新账号)。正是由于这个缘由,GET 请求一般认为是“安全”的,由于他们不会致使应用的改变。

  

  HTTP POST

  

  显然,除了简单的查看页面以外,应该还有更多与网站进行交互的操做。咱们也可以向应用发送数据,例如经过表单。为了达到这样的目的,就须要一种不一样类型的请求方法:POST。POST 请求一般携带由用户输入的数据,web 应用收到以后会产生一些行为。经过在表单里输入你的信息登陆一个网站,就是 POST 表单的数据给 web 应用的。

  

  不一样于 GET 请求,POST 请求一般会致使应用状态的改变。在咱们的例子中,当表单 POST 以后,一个新的帐户被建立。不一样于 GET 请求,POST 请求不老是生成一个新的 HTML 页面发送到客户端,而是客户端使用响应的响应码(response code)来决定对应用的操做是否成功。

  

  HTTTP Response Codes

  

  一般来讲,web 服务器返回 200 的响应码,意思是,“我已经完成了你要求我作的事情,一切都正常”。响应码老是一个三位数字的代号,web 应用在每一个响应的同时都发送一个这样的代号,代表给定的请求的结果。响应码 200 字面意思是“OK”,是响应一个 GET 请求大多状况下都使用的代号。然而对于 POST 请求, 可能会有 204(“No Content”)发送回来,意思是“一切都正常,可是我不许备向你显示任何东西”。

  

  Web 应用

  

  你能够仅仅使用 HTTP GET 和 POST 作不少事情。一个应用程序负责去接收一个 HTTP 请求,同时给以 HTTP 响应,一般包含了请求页面的 HTML。POST 请求会引发 web 应用作出一些行为,多是往数据库中添加一条记录这样的。还有不少其它的 HTTP 方法,可是咱们目前只关注 GET 和 POST。

  

  那么最简单的 web 应用是什么样的呢?咱们能够写一个应用,让它一直监听 80 端口(著名的 HTTP 端口,几乎全部 HTTP 都发送到这个端口上)。一旦它接收到等待的客户端发送的请求链接,而后它就会回复一些简单的 HTML。

  

  下面是程序的代码:

  

  import socketHOST = ''PORT = 80listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)listen_socket.bind((HOST, PORT))listen_socket.listen(1)connection, address = listen_socket.accept()request = connection.recv(1024)connection.sendall(b"""HTTP/1.1 200 OKContent-type: text/html

  

  <html>    <body>        <h1>Hello, World!</h1>    </body></html>""")connection.close()

  

  (若是上面的代码不工做,试着将 PORT 改成相似 8080 这样的端口。)

  

  这个代码接收简单的连接和简单的请求,无论请求的 URL 是什么,它都会响应 HTTP 200(因此,这不是一个真正意义上的 web 服务器)。Content-type:text/html 行代码的是 header 字段,header 用来提供请求或者响应的元信息。这样,咱们就告诉了客户端接下来的数据是 HTML。

  

  请求的剖析

  

  若是看一下测试上面程序的 HTTP 请求,你会发现它和 HTTP 响应很是相似。第一行<HTTP Method> <URL> <HTTP version>,在这个例子中是 GET / HTTP/1.0。第一行以后就是一些相似Accept: */* 这样的头(意思是咱们但愿在响应中接收任何内容)。

  

  咱们响应和请求有着相似的第一行,格式是<HTTP version> <HTTP Status-code> <Status-code Reason Phrase>,在外面的例子中是HTTP/1.1 200 OK 。接下来是头部,与请求的头部有着相同的格式。最后是响应的实际包含的内容。注意,这会被解释为一个字符串或者二进制文件, Content-type 头告诉客户端怎样去解释响应。

  

  解决路由和模板两大问题

  

  围绕创建 web 应用的全部问题中,两个问题尤为突出:

  

  1.咱们如何将请求的 URL 映射处处理它的代码上?

  

  2.咱们怎样动态地构造请求的 HTML 返回给客户端,HTML 中带有计算获得的值或者从数据库中取出来的信息?

  

  每一个 web 框架都以某种方法来解决这些问题,也有不少不一样的解决方案。用例子来讲明更容易理解,因此我将针对这些问题讨论 Django 和 Flask 的解决方案。可是,首先咱们还须要简单讨论一下 MVC 。

  

  Django 中的 MVC

  

  Django 充分利用 MVC 设计模式。 MVC,也就是 Model-View-Controller (模型-视图-控制器),是一种将应用的不一样功能从逻辑上划分开。models 表明的是相似数据库表的资源(与 Python 中用 class 来对真实世界目标建模使用的方法大致相同)。controls 包括应用的业务逻辑,对 models 进行操做。为了动态生成表明页面的 HTML,须要 views 给出全部要动态生成页面的 HTML 的信息。

  

  在 Django 中有点让人困惑的是,controllers 被称作 views,而 views 被称为 templates。除了名字上的有点奇怪,Django 很好地实现了 MVC 的体系架构。

  

  Django 中的路由

  

  路由是处理请求 URL 到负责生成相关的 HTML 的代码之间映射的过程。在简单的情形下,全部的请求都是有相同的代码来处理(就像咱们以前的例子那样)。变得稍微复杂一点,每一个 URL 对应一个 view function 。举例来讲,若是请求 www.foo.com/bar 这样的 URL,调用 handler_bar() 这样的函数来产生响应。咱们能够创建这样的映射表,枚举出咱们应用支持的全部 URL 与它们相关的函数。

  

  然而,当 URL 中包含有用的数据,例如资源的 ID(像这样 www.foo.com/users/3/) ,那么这种方法将变得很是臃肿。咱们如何将 URL 映射到一个 view 函数,同时如何利用咱们想显示 ID 为 3 的用户?

  

  Django 的答案是,将 URL 正则表达式映射到能够带参数的 view 函数。例如,我假设匹配^/users/(?P<id>\d+)/$ 的 URL 调用 display_user(id) 这样的函数,这儿参数 id 是正则表达式中匹配的 id。这种方法,任何 /users/<some_number>/ 这样的 URL 都会映射到 display_user 函数。这些正则表达式能够很是复杂,包含关键字和参数。

  

  Flask 中的路由

  

  Flask 采起了一点不一样的方法。将一个函数和请求的 URL 关联起来的标准方法是经过使用 route() 装饰器。下面是 Flask 代码,在功能上和上面正则表达式方法相同:

  

  @app.route('/users/<id:int>/')

  

  def display_user(id):

  

  # ...

  

  就像你看到的这样,装饰器使用几乎最简单的正则表达式的形式来将 URL 映射到参数。经过传递给route() 的 URL 中包含的 <name:type> 指令,能够提取到参数。路由像 /info/about_us.html 这样的静态 URL,能够像你预想的这样 @app.route('/info/about_us.html') 处理。

  

  经过 Templates 产生 HTML

  

  继续上面的例子,一旦咱们有合适的代码映射到正确的 URL,咱们如何动态生成 HTML?对于 Django 和 Flask,答案都是经过 HTML Templating。

  

  HTML Templating 和使用 str.format() 相似:须要动态输出值的地方使用占位符填充,这些占位符后来经过 str.format() 函数用参数替换掉。想象一下,整个 web 页面就是一个字符串,用括号标明动态数据的位置,最后再调用 str.format() 。Django 模板和 Flask 使用的模板引擎 Jinja2 都使用的是这种方法。

  

  然而,不是全部的模板引擎都能相同的功能。Django 支持在模板里基本的编程,而 Jinja2 只能让你执行特定的代码(不是真正意义上的代码,但也差很少)。Jinja2 能够缓存渲染以后的模板,让接下来具备相同参数的请求能够直接从缓存中返回结果,而不是用再次花大力气渲染。

  

  数据库交互

  

  Django 有着“功能齐全”的设计哲学,其中包含了一个 ORM(Object Realational Mapper,对象关系映射),ORM 的目的有两方面:一是将 Python 的 class 与数据库表创建映射,而是剥离出不一样数据库引擎直接的差别。没人喜欢 ORM,由于在不一样的域之间映射永远不完美,然而这还在承受范围以内。Django 是功能齐全的,而 Flask 是一个微框架,不包括 ORM,尽管它对 SQLAlchemy 兼容性很是好,SQLAlchemy 是 Django ORM 的最大也是惟一的竞争对手。

  

  内嵌 ORM 让 Django 有能力建立一个功能丰富的 CRUD 应用,从服务器端角度来看,CRUD(CreateRead Update Delete)应用很是适合使用 web 框架技术。Django 和 Flask-SQLchemy 能够直接对每一个 model 进行不一样的 CRUD 操做。

  

  总结:

  

  到如今为止,web前端框架的目的应该很是清晰了:向程序员隐藏了处理 HTTP 请求和响应相关的基础代码。至于隐藏多少这取决于不一样的框架,Django 和 Flask 走向了两个极端:Django 包括了每种情形,几乎成了它致命的一点;Flask 立足于“微框架”,仅仅实现 web 应用须要的最小功能,其它的不经常使用的 web 框架任务交由第三方库来完成。

  

  可是最后要记住的是,Python web 框架都以相同的方式工做的:它们接收 HTTP 请求,分派代码,产生 HTML,建立带有内容的 HTTP 响应。事实上,全部主流的服务器端框架都以这种方式工做的( JavaScript 框架除外)。希望了解了这些框架的目的,你可以在不一样的框架之间选择适合你应用的框架进行开发。

相关文章
相关标签/搜索