专栏名称: 编程派
Python程序员都在看的公众号,跟着编程派一起学习Python,看最新国外教程和资源!
目录
相关文章推荐
Python爱好者社区  ·  同事年底绩效是C,提离职领导死活不让走,后来 ... ·  昨天  
Python爱好者社区  ·  刚刚,奥特曼晒出早产娃引爆全网!两个爸爸孕育 ... ·  2 天前  
Python爱好者社区  ·  640页的python教程 ·  昨天  
小小的python学习社  ·  Python100道真题题库 ·  昨天  
Python爱好者社区  ·  DeepSeek 被放弃了,阿里牛逼! ·  3 天前  
51好读  ›  专栏  ›  编程派

什么是 Web 框架?

编程派  · 公众号  · Python  · 2017-04-25 12:22

正文

原文: http://cizixs.com/2015/09/21/what-is-a-web-framework

全文约 6805 字,读完可能需要 10 分钟。

原文地址: http://jeffknupp.com/blog/2014/03/03/what-is-a-web-framework/

Web 应用框架,简称为 web 框架 ,是编写 web 应用程序的基石。不管简单的博客系统,还是 Ajax 为主的应用,网络上所有的页面都是代码构成的。进来我发现,很多想学习诸如 Flask 或者 Django 等 web 框架的开发者,并不很了解 web 框架是什么,它们的作用和工作原理。

这篇文章,我将会讲一下这个通常会被忽略的话题。希望读完这篇文章,你能比较深刻地理解 web 框架到底是什么,还有为什么会有 web 框架。这些知识将有利于你学习新的 web 框架,而且在选择 web 框架的时候有法可依。

WEB 是什么工作的?

在讨论框架之前,我们要先了解一下网页是怎么工作。我们就从你在浏览器输入一个网址,摁下 enter 键说起。打开你的浏览器,输入 http : //jeffknupp.com (译者注:原作者的个人网站首页),我们来看看你的浏览器做了那些事情(DNS 查询的 buffer 就略过),才能显示你看到的网页。

web servers,和 web … servers …

浏览器接接收到的网页都是 HTML 文件, HTML 是一种描述网页内容和结构的语言。负责给浏览器发送 HTML 的程序称为 web server,容易混淆的是,这个应用程序所在的机器通常也被称为 web server。

最重要的一点是,所有的 web 应用做的事情就是把 HTML 内容发送给浏览器。不论这个 web 应用有多么复杂,最终的任务都是把 HTML (我故意忽略掉其他格式的内容,比如 JSON,CSS 文件,因为原理都是一样的)发送给浏览器。

问题来了:web 应用如何知道要发送什么内容给浏览器呢? 答案:它会发送浏览器请求的内容。

HTTP

浏览器从 web server 下载内容所用的是 HTTP 协议(协议在计算机科学中,指的是双方通信所共同遵循的数据格式和通信步骤)。 HTTP 协议的基础是 请求-应答 ( request - response ) 模型。客户端(你的浏览器) 请求 某台物理机上 web 应用的数据,web server 则负责 应答 请求的数据。

有个重要的事情是:所有的通信都是客户端(你的浏览器)发起的。服务端(web server)是不可能主动连接你,发送没有请求的数据的。如果你收到了数据,只是因为你的浏览器主动请求了这些数据。

HTTP 方法

HTTP 协议的每条消息都有对应的方法(method),不同的方法对应了客户端能发起的不同请求,也对应了客户端不同的意图。比如, 请求 网页的 HTML 和提交一个表格在逻辑上是不同的,所以这两种方法需要两种不同的方法。

HTTP GET

顾名思义, GET 方法就是从 web server 获取(get)数据, GET 请求也是目前最常用的 HTTP 请求。 处理 GET 请求的过程中,web 应用只需要返回请求的数据,无需其他操作。尤其是,不应该修改应用的状态(比如, GET 请求不应该导致一个新用户被创建)。因为这个原因, GET 请求通常被看做是 安全 的。

HTTP POST

和网站的交互,明显不只是查看网页的。我们还会通过表格等形式发送数据给 web 应用,这些操作需要用到另外一种请求: POST POST 请求通常会传递用户创建的信息,导致 web 应用执行某些动作。输入自己的信息,来注册某个网站就会用到 POST 请求,请求中会包含你输入的数据。

GET 请求不同的是, POST 请求通常会导致 web 应用状态的改变。上面提及的例子中,表单被提交后,一个新的用户会被创建。还有一点不同, POST 请求的结果可能不会返回 HTML 数据给客户端,客户端需要通过 response code 来判断操作是否成功。

HTTP response code

正常情况下,web server 会返回 200 的 response code,意思是:我已经完成了你要我做的事情,并且一切都没有问题。 response code 是三位的数字,每次应答都要包含一个 response code,来标识请求的结果。 200 表示 OK,是 GET 方法常见的返回值。 POST 请求经常会返还 204 (No contnet),表示:一切正常,但是我没有数据可以展示给你。

还需要注意的是: POST 请求发送给的 url,可能和数据发送出去的 url 不同。继续以我们的注册页面为例,注册表可能位于 http : //foo.com/signup ,点击 submit 之后,包含着注册数据的 POST 请求可能被发送到 http : //foo.com/process_signup POST 请求要发送到的地址,一般在注册表格的 HTML 源码里指定。

Web 应用

掌握 GET POST 方法就能做很多事情,因为它们是 web 上最常用的两个方法。总结一下,web 应用就是接收 HTTP 请求,然后返回 HTTP 应答,一般是包含请求数据的 HTML POST 方法会导致 web 应用执行某些动作,例如在数据库添加一条记录。当然还有其他的 HTTP 方法,但目前我们只需要关心 GET POST 就足够啦。

最简单的 web 应用长什么样呢?我们就来写一个监听在 80 端口的 web 应用,一旦和客户端建立连接,就等待客户端发起请求,并返回非常简单的 HTML

这个程序是这样的:

  1. import socket

  2. HOST = ''

  3. PORT = 80

  4. listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  5. listen_socket.bind((HOST, PORT))

  6. listen_socket .listen(1)

  7. connection, address = listen_socket.accept()

  8. request = connection.recv(1024)

  9. connection.sendall("""HTTP/1.1 200 OK

  10. Content-type: text/html

  11.    

  12.        

    Hello, World!

  13.    

  14. """)

  15. connection.close()

(如果上面的程序报端口错误,可以把 PORT 的值修改成其他值,比如 8080 。)

上面的代码只会接收一个连接和一个请求,不管请求的 URL 是什么,都会返回同样的 HTTP 内容,response code 是 200 。(很明显,这不算真正的 web server)。在这个例子,我们告诉客户端,返回的数据格式为 HTML ,而不是其他的格式,比如 JSON

request 请求解析

如果看一下上面例子中发送的 HTTP 请求(译者注:可以使用 chrome 的 inspect elements -> Network,或者抓包工具 tcpdump 等工具查看发送的 HTTP 请求),就会发现它和应答很相似。请求的第一行是:

  1. Method> version>

在这个例子里就是 GET / HTTP / 1.1 。第一行后面跟着的是请求的头部(headers),比如 Accept : * /* (表示可以接收任何格式的内容作为应答)。基本上就这么多。

我们发送的应答也是类似的格式,第一行是:

  1. version> Status-Code> Reason-Phrase>

这个例子中就是 HTTP / 1.1 200 OK 。然后是头部,和请求的头部一样。最后是应答的实际内容。注意:应答也可能是字符串或者二进制对象,头部的 Content - typ 就是来标识应答内容,让客户端来解析的。

web server 更多琐碎的细节

要在上面的例子基础上继续扩展的话,还有很多需要我们来解决的问题:

  1. 怎么查看请求的 URL,然后返回不同的页面?

  2. 除了 GET 请求,怎么处理 POST 请求?

  3. 怎么处理很复杂的概念,比如 sessions 和 cookies?

  4. 如何扩展这个应用,让它可以同时处理数千条连接?

可以想象,没人会愿意每次编写 web 应用的时候都要自己处理这些问题。为了解决这个难题,就会存在很多的软件包帮你处理这些烦人的细节,让开发者可以把心思放到业务逻辑上。记住,不管 web 框架多么负责,其最核心的功能和我们上面的例子是一样的:监听客户端请求,然后返回 HTML 给客户端。

NOTE:客户端的框架和上面的内容迥然不同。

解决两个难题:路由(routing)和模板(templates)

在构建 web 应用的所有的问题中,有两个比较突出:

  1. 怎么把请求 URL 和处理它的那部分代码对应起来?

  2. 怎么动态地生产请求内容?包括所有要计算的值,和从数据库获取的信息?

每个 web 框架解决这两个问题的方法都不太相同,我们就举 Flask 和 Django 的例子来说明这个问题。首先,我们还要来说一下 MVC 模式。

Django 中的 MVC

Django 采用 MVC 模式, 所以要求使用这个框架的代码都遵循这个模式。 MVC ,是 Model-View-Controller 的缩写,用来分离应用的不同责任。数据库表所代表的资源用 models 来表示, controllers 负责应用的业务逻辑和操作 models。 Views 则负责动态生成代表页面的 HTML

不过容易让人混淆的是,django 中 controllers 被称作 views ,而 views 被称为 templates 。除了命名外,django 算是比较直接的 MVC 架构。

Django 的路由(routing)机制

这里说的路由(routing)就是把请求的 URL 对应到处理生成相关 HTML 的代码。最简单的例子,所有的请求都是相同的代码处理(就是我们之前编写的代码)。复杂一点呢,每个的 URL 都对应一个不同的 view







请到「今天看啥」查看全文