--- title: 服务端web框架 slug: learn/Server-side/First_steps/Web_frameworks tags: - web框架 - 介绍 - 初学者 - 学习 - 指导 - 服务器 - 服务器端编程 - 编码 translation_of: Learn/Server-side/First_steps/Web_frameworks ---
前面的文章向你展示了web客户端和服务器之间的通信是什么样子的,HTTP的请求和回应之间的性质,以及服务器端应用为了回应来自web浏览器的请求的需要做的事情。有了这些知识后,现在是时候来探索一个web框架是如何简化这些任务的,并且告诉你应该如何为你的第一个服务器端应用选择一个框架。
预先要求: | 基础电脑素养。对于服务器端代码是如何处理并响应HTTP请求有深刻的理解。(参见Client-Server overview) |
---|---|
目标: | 理解web框架是如何简化服务器端代码的开发和维护的,并且帮助读者思考如何为他们自己的开发项目选择一个框架。 |
下面的部分通过使用一些来自web框架的代码段来说明一些要点。如果不能完全看懂代码也不用太在意。我们在“框架详解”模块会帮助你完全理解。
服务器端框架(亦称 "web 应用框架") 使编写、维护和扩展web应用更加容易。它们提供工具和库来实现简单、常见的开发任务, 包括 路由处理, 数据库交互, 会话支持和用户验证, 格式化输出 (e.g. HTML, JSON, XML), 提高安全性应对网络攻击.
下一节将详细介绍web框架如何简化web应用程序开发。然后,我将阐述一些选择web框架的标准,并给你列出一些选项。
你并不是必须得使用一个服务器端的web框架,但是我们强烈建议你使用框架——框架会使得你的生活更美好。
这个部分我们讲一下web框架通常会提供的功能(并不是说每一个框架一定会提供下面的所有功能!)
从上一篇文章中我们知道,web服务器和浏览器通过HTTP协议进行通信——服务器等待来自浏览器的HTTP请求然后在HTTP回应中返回相关信息。web框架允许你编写简单语法的代码,即可生成处理这些请求和回应的代码。这意味着你的工作变得简单、交互变得简单、并且使用抽象程度高的代码而不是底层代码。
每一个“view”函数(请求的处理者)接受一个包含请求信息的HttpRequest
对象,并且被要求返回一个包含格式化输出的HttpResponse
(在下面的例子中是一个字符串)。
# Django view function from django.http import HttpResponse def index(request): # Get an HttpRequest (request) # perform operations using information from the request. # Return HttpResponse return HttpResponse('Output string to return')
大多数的站点会提供一系列不同资源,通过特定的URL来访问。如果都放在一个函数里面,网站会变得很难维护。所以web框架提供一个简单机制来匹配URL和特定处理函数。这种方式对网站维护也有好处,因为你只需要改变用来传输特定功能的URL而不用改变任何底层代码。
不同的框架使用不同机制进行匹配。比如Flask(Python)框架通过使用装饰器来增加视图的路由。
@app.route("/") def hello(): return "Hello World!"
然而,Django则期望开发者们定义一张URL pattern和视图函数URL的匹配列表。
urlpatterns = [ url(r'^$', views.index), # example: /best/myteamname/5/ url(r'^(?P<team_name>\w.+?)/(?P<team_number>[0-9]+)/$', views.best), ]
数据在HTTP请求中的编码方式有很多种。一个从服务器获得文件或者数据的HTTP GET
请求可能会按照URL参数中要求的或者URL结构中的方式进行编码。一个更新服务器上数据的HTTP POST
请求则会在请求主体中包含像“POST data”这样的更新信息。HTTP请求也可能包含客户端cookie中的即时会话和用户信息。
web框架提供一个获得这些信息的适合编程语言的机制。比如,Django传递给视图函数的HttpRequest
对象包含着获得目标URL的方式和属性、请求的类型(比如一个HTTP GET
)、GET
或者POST
参数、cookie或者session数据等等。Django也可以通过在URL匹配表中定义“抓取模式”来在URL结构中传递编码了的信息(如上面的编码片段中的最后一行)。
网站使用数据库来存储与用户分享的信息和用户个人信息。web框架通常会提供一个数据库层来抽象数据库的读、写、查询和删除操作。这一个抽象层被称作对象关系映射器(ORM)。
使用对象关系映射器有两个好处:
比如,Django框架提供一个对象关系映射,并且将用来定义数据库记录的结构称作模型。模型制定被存储的字段类型,可能也会提供那些要被存储的信息的验证(比如,一个email字段只允许合法email地址)。字段可能也会指明最大信息量、默认值、选项列表、帮助文档、表单标签等。这个模型不会申明任何底层数据库的信息,因为这是一个只能被我们的代码改变的配置信息。
下面第一个代码片段展示了一个简单的为Team
对象设计的Django模型。这个模型会使用字符字段来存储一个队伍的名字和级别,同时还指定了用来存储每一条记录的最大字符数量。team_level
是一个枚举字段,所以我们也提供了一个被存储的数据和被展示出来的选项之间的匹配,同时指定了一个默认值。
#best/models.py from django.db import models class Team(models.Model): team_name = models.CharField(max_length=40) TEAM_LEVELS = ( ('U09', 'Under 09s'), ('U10', 'Under 10s'), ('U11, 'Under 11s'), ... #list our other teams ) team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
Django模型提供了简单的搜索数据库的查询API。这可以通过使用不同标准来同时匹配一系列的字段(比如精确、不区分大小写、大于等等),并且支持一些复杂的陈述(比如,你可以指定在U11水平的队伍中搜索队伍名字中以“Fr”开头或者“al”结尾的队伍)。
第二个代码片段展示了一个视图函数(资源处理器),这个视图函数用来展示所有U09水平的队伍——通过指明过滤出所有team_level
字段能准确匹配'U09'的队伍(注意过滤规则如何传递给filter( )
,它被视为一个变量:team_level__exact
,由字段名、匹配类型和分隔它们的双重下划线组成)。
#best/views.py from django.shortcuts import render from .models import Team def youngest(request): list_teams = Team.objects.filter(team_level__exact="U09") context = {'youngest_teams': list_teams} return render(request, 'best/index.html', context)
web框架经常提供模板系统。这些允许你制定输出文档的结构,使用为那些数据准备的将在页面生成时添加进去的占位符。模板经常是用来生成HTML的,但是也可以用来生成一些其他的文档。
框架提供一个机制,使得从存储的数据中生成其他格式数据变得简单,包括{{glossary("JSON")}}和{{glossary("XML")}}。
比如,Django模板允许你通过使用“双重花括号”(如{
{ variable_name
}
}
)来指定变量,当页面被渲染出来时,这些变量会被从视图函数传递过来的值代替。模板系统也会提供表达支持(通过语法{% expression %}来实现
),这样就允许模板进行一些简单的操作比如迭代传递给模板的值列表。
Note: 很多其他的模板系统使用相似的语法,比如:Jinja2 (Python), handlebars (JavaScript), moustache (JavaScript), 等。
下面的代码片段展示了它们如何工作的。下面的内容接着从上一个部分而来的“youngest team”实例,HTML模板通过视图函数传进一个叫做youngest_teams的值列表。在HTML骨架中我们有一个初步检查youngest_teams变量是否存在的表示,然后会在for循环里面进行迭代。在每一次迭代中模板会以列表元素的形式展示队伍的team_name值。
#best/templates/best/index.html <!DOCTYPE html> <html lang="en"> <body> {% if youngest_teams %} <ul> {% for team in youngest_teams %} <li>\{\{ team.team_name \}\}</li> {% endfor %} </ul> {% else %} <p>No teams are available.</p> {% endif %} </body> </html>
几乎对于你想要使用的每一种语言都有大量的web框架(我们在下面的部分列举了一些比较受欢迎的框架)。有这么多选择,导致很难决定选择哪个框架为你的新web应用提供最好的开端。
一些影响你决定的因素有:
可能还有其他一些原因,包括许可证、框架是否处于动态发展过程中等等。
如果你是一个完全的初学者,那么你可能会基于“易于学习”来选择你的框架。除了语言本身的“易于学习”之外,帮助新手的高质量的文档/教程和一个活跃的社区是你最有价值的资源。在后续课程中,我们选取了Djnago(Python)和Express(Node/Javascript)来编写我们的实例,主要因为它们很容易上手并且有强大的支持。
注意: 我们可以去 Django (Python) 和 Express (Node/JavaScript) 的主页上去看看它们的文档和社区。
让我们继续,来讨论几个特定的服务器端框架。
下面的服务器端框架体现了现在最受欢迎的几个。它们有你需要用来提升效率的一切东西——它们是开源的,一直保持发展的态势,有着富有激情的社区,社区里的人创作出文档并且在讨论板上帮助使用者,并且被使用在很多高质量的网站上。当然还有很多其他非常棒的框架,你可以使用搜索引擎探索一下。
注意:(部分)解释来自框架的官方网站!
Django是一个高水平的python web框架,它鼓励快速的开发和简洁、务实的设计。它由非常有经验的开发者创建的,考虑到了web开发中会遇到的大多数难题,所以你无需重复造轮就能够专心编写你的应用。
Django遵循“Batteries included”哲学,并且提供了几乎所有大多开发者们想要“开箱即用”的东西。因为它已经包含了所有东西,它作为一个整体一起工作,遵循着一致的设计原则,并且有扩展的、持续更新的文档。它也是非常快、安全和易于扩展的。基于python,Django代码非常容易阅读和维护。
使用Django的主流网站(从Django官网首页看到的)包括: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest, Open Stack.
Flask是python的一个微型框架
虽然体量很小,Flask却可以开箱即用地创造出完备网站。它包含一个开发服务器和调试器,并且包含对于 Jinja2 模板的支持, 安全的cookie, unit testing, 和 RESTful request dispatching。它有很好的文档和一个活跃的社区。
Flask已经非常火爆了,部分因为那些需要在小型的、资源受限的系统中提供web服务的开发者们。(比如,在Raspberry Pi, Drone controllers等上面运行服务器)。
Express 针对 Node.js 的快速的、unopinioned、灵活的、小型的web框架(node是用来运行Javascript的无浏览器的环境)。它为web和移动应用提供强大的系列功能,并且传输有用的HTTP工具、方法和middleware.
Express非常受欢迎,主要因为它减轻了客户端Javascript程序到服务器端开发的迁移,并且部分因为它是资源节约型(底层的node环境在单线程中使用轻量级多任务处理,而不是为每个web请求提供单独的进程)。
因为Express是一个小型的web框架,它几乎不包含任何你可能想要使用的组件(比如,数据库接口和对用户和会话的支持通过独立的库来完成)。有很多独立的、非常好的组件,但是有时候你可能很难决定对于特定目的而言哪一个是最好的!
很多非常受欢迎的服务器端编程和全栈框架(同时包括服务器端和客户端框架),包括 Feathers, ItemsAPI, KeystoneJS, Kraken, LEAN-STACK, LoopBack, MEAN, 和 Sails.
大量的profile company使用Express,包括优步、Accenture、IBM等(这里是一张列表).
Rails (通常被称作"Ruby on Rails")是一个为Ruby语言编写的web框架。
Rails遵循了和Django非常相似的设计哲学。正如Django一样,它提供了检索URLs的标准机制、从数据库中访问数据、从模板中生成HTML页面、格式化数据{{glossary("JSON")}} 或者 {{glossary("XML")}}。同样的,它也鼓励如 DRY (不要重复你自己)的设计模板——尽可能地只写一次代码、MVC(模板-视图-控制中心)以及很多其他的一些。
当然,还有很多由于因为具体设计决定和语言的特性导致的差异。
Rails被用在很多站点中,包括: Basecamp, GitHub,Shopify, Airbnb, Twitch, SoundCloud,Hulu, Zendesk, Square, Hi
ASP.NET 是一个由微软开发的开源Web框架,用于构建现代的Web应用程序和服务。通过ASP.NET你能快速创建基于HTML、CSS、JavaScript的网站,并且能满足大量用户的需求,还可以很容易地添加诸如Web API、数据表单、即时通讯的功能。
ASP.NET的特点之一就是它建立在 Common Language Runtime (CLR公共语言运行时)之上。这使得程序员可以使用任何支持的.NET语言(如C#、Visual Basic)来编写ASP.NET代码。和很多微软的产品一样,它得益于出色的开发工具(通常是免费的)、活跃的开发者社区,以及详尽的文档。
ASP.NET被微软、Xbox、Stack Overflow等采用。
Mojolicious是为Perl语言设计的新一代Web框架。
在Web的早期阶段,许多人都为了一个叫做 CGI 的优秀的Perl库而学过Perl。它简单到即使你不是太懂这门语言也可以开始使用,而且也强大到足以让你可以用下去。Mojolicious通过最新的技术实现了这个想法。
Mojolicious提供的一些功能是:
这篇文章展示了web框架如何使得编写和维护服务器端代码变得简单。它也提供了对于几个流行的框架的评价,还讨论了选择一个web框架的标准。你现在至少应该了解了如何为你的服务器端开发选择一个web框架。如果还没有,也不要担心——接下来我们给你一个详细的Django和Express教程,从而让你有一些使用web框架的实战经验。
这个模块的下一章节我们会稍微转变一下思路,我们会讨论一下网络安全。
{{PreviousMenuNext("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps/Website_security", "Learn/Server-side/First_steps")}}