From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../first_steps/client-server_overview/index.html | 317 +++++++++++++++++++++ .../zh-cn/learn/server-side/first_steps/index.html | 46 +++ .../first_steps/introduction/index.html | 239 ++++++++++++++++ .../first_steps/web_frameworks/index.html | 298 +++++++++++++++++++ .../first_steps/website_security/index.html | 165 +++++++++++ 5 files changed, 1065 insertions(+) create mode 100644 files/zh-cn/learn/server-side/first_steps/client-server_overview/index.html create mode 100644 files/zh-cn/learn/server-side/first_steps/index.html create mode 100644 files/zh-cn/learn/server-side/first_steps/introduction/index.html create mode 100644 files/zh-cn/learn/server-side/first_steps/web_frameworks/index.html create mode 100644 files/zh-cn/learn/server-side/first_steps/website_security/index.html (limited to 'files/zh-cn/learn/server-side/first_steps') diff --git a/files/zh-cn/learn/server-side/first_steps/client-server_overview/index.html b/files/zh-cn/learn/server-side/first_steps/client-server_overview/index.html new file mode 100644 index 0000000000..c8bb70acd3 --- /dev/null +++ b/files/zh-cn/learn/server-side/first_steps/client-server_overview/index.html @@ -0,0 +1,317 @@ +--- +title: 客户端服务端交互概述 +slug: learn/Server-side/First_steps/Client-Server_overview +tags: + - 服务器端编程 +translation_of: Learn/Server-side/First_steps/Client-Server_overview +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/First_steps/Introduction", "Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}
+ +

既然你已经了解了服务器端编程的目的和潜在的好处,接下来我们将非常细致地去说明当服务器接收到了来自浏览器的“动态请求”时到底发生了什么。因为大多数的服务器端代码通过相似的方式来处理请求并做出响应,这将帮助你理解当编写你自己的大量代码时你需要做什么。

+ + + + + + + + + + + + +
预备知识:基本电脑素养、对于什么是网络服务器的基本了解
目标:理解在动态网站中的客户端-服务器端交互过程,尤其是服务器端代码需要承担的工作
+ +

到目前为止的讨论中还没有真正的代码,因为我们还没有选择一个web框架来写我们的代码呢!然而这个讨论仍旧十分重要,因为我们描述的行为必须通过你的服务器端代码来实现,不管你选择什么编程语言和web框架。

+ +

网络服务器和HTTP(入门)

+ +

网络浏览器通过超文本标记语言传输协议(HTTP)与网络服务器(web servers)。 当你在网页上点击一个链接、提交一个表单、或者进行一次搜索的时候,浏览器发送一个HTTP请求给服务器。

+ +

这个请求包含:

+ + + +

网络服务器等待来自客户的请求信息,当请求到达时处理它们,然后发给浏览器HTTP响应消息。回应包含一个HTTP响应状态码(HTTP Response status code)来暗示请求是否成功 (比如 "200 OK" 连接成功, "404 Not Found" 资源没有找到, "403 Forbidden" 用户没有被授权查看资源, 等等).  一个成功的响应主体,会包含GET请求所请求的资源.

+ +

当一个HTML页面被返时,页面会被网络浏览器呈现出来。作为处理工作的一部分,浏览器会发现指向其他资源的链接(比如,一个HTML页面通常会参考Javascript和CSS页面),并且会发送独立的HTTP请求来下载这些文件。

+ +

静态网站和动态网站(在接下来的部分讨论到的)正是使用同一种通信协议/模式

+ +

GET请求/响应举例

+ +

你可以通过点击一个链接或者在网站进行一次搜索(比如搜索引擎的首页)做出一次简单的GET请求。比如,当你在MDN上进行一次对“客户端概览”词条的搜索时,HTTP请求就被发送出去了,你将会看到正如下面一样被展示出来的文本信息(展示出来的信息不一定是相同的,因为其中一部分信息还取决于你的浏览器)。

+ +
+

HTTP消息的格式是在“网络标准”(RFC7230)中定义的。你不需要知道这个标准的细节,但是现在你至少得知道所有这些是来自哪儿的!

+
+ +

请求

+ +

每一行请求都包含着相关信息。第一部分被称为header,并且包含着关于这个请求的有用信息,同样地一个HTML head包含着关于HTML文档的有用信息(但是却没有自身的实际内容,内容在主体里面)。

+ +
GET https://developer.mozilla.org/en-
+US/search?q=client+server+overview&topic=apps&topic=html&topic=css&topic=js&topic=api&topic=webdev HTTP/1.1
+Host: developer.mozilla.org
+Connection: keep-alive
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Referer: https://developer.mozilla.org/en-US/
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
+Accept-Language: en-US,en;q=0.8,es;q=0.6
+Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=False; dwf_sg_task_completion=False; _gat=1; _ga=GA1.2.1688886003.1471911953; ffo=true
+
+ +

第一行和第二行包含了我们在上面讨论过的大部分信息

+ + + +

最后一行包括一些关于客户端cookies的信息——你可以看到在这种情况下cookies包含一个为处理远程会话准备的ID(Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; ...)。

+ +

剩余几行包含着所使用的浏览器以及浏览器所能处理的回应类型等信息。比如,你可以在下面看到这些相关信息:

+ + + +

请求也可以有一个请求体,不过在这个例子中请求的请求体是空的。

+ +

回应

+ +

针对这个请求的回应的第一部分内容展示如下。The header包含了如下信息:

+ + + +

在消息的末尾我们可以看到主体内容——包含了针对请求返回的真实的HTML。

+ +
HTTP/1.1 200 OK
+Server: Apache
+X-Backend-Server: developer1.webapp.scl3.mozilla.com
+Vary: Accept,Cookie, Accept-Encoding
+Content-Type: text/html; charset=utf-8
+Date: Wed, 07 Sep 2016 00:11:31 GMT
+Keep-Alive: timeout=5, max=999
+Connection: Keep-Alive
+X-Frame-Options: DENY
+Allow: GET
+X-Cache-Info: caching
+Content-Length: 41823
+
+
+
+<!DOCTYPE html>
+<html lang="en-US" dir="ltr" class="redesign no-js"  data-ffo-opensanslight=false data-ffo-opensans=false >
+<head prefix="og: http://ogp.me/ns#">
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=Edge">
+  <script>(function(d) { d.className = d.className.replace(/\bno-js/, ''); })(document.documentElement);</script>
+  ...
+
+ +

header的剩余部分还包括一些回应的其他信息(比如回应在什么时候生成的),有关服务器的信息,还有它期望浏览器如何处理这个包(比如, X-Frame-Options: DENY 告诉浏览器不允许这个网页嵌入在其他网站的HTML元素{{htmlelement("iframe")}}上。

+ +

POST 请求/响应举例

+ +

当你提交一个表单,并且希望表单所包含的信息存储到服务器的时候,你就生成了一次HTTP POST请求。

+ +

请求

+ +

下面的文本展示了当用户在网站上提交新的文件的时候,生成的一个HTTP请求的格式和之前展示的GET请求是非常相似的,只是第一行标识这个请求为POST。

+ +
POST https://developer.mozilla.org/en-US/profiles/hamishwillee/edit HTTP/1.1
+Host: developer.mozilla.org
+Connection: keep-alive
+Content-Length: 432
+Pragma: no-cache
+Cache-Control: no-cache
+Origin: https://developer.mozilla.org
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
+Content-Type: application/x-www-form-urlencoded
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Referer: https://developer.mozilla.org/en-US/profiles/hamishwillee/edit
+Accept-Encoding: gzip, deflate, br
+Accept-Language: en-US,en;q=0.8,es;q=0.6
+Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; _gat=1; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=False; dwf_sg_task_completion=False; _ga=GA1.2.1688886003.1471911953; ffo=true
+
+csrfmiddlewaretoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT&user-username=hamishwillee&user-fullname=Hamish+Willee&user-title=&user-organization=&user-location=Australia&user-locale=en-US&user-timezone=Australia%2FMelbourne&user-irc_nickname=&user-interests=&user-expertise=&user-twitter_url=&user-stackoverflow_url=&user-linkedin_url=&user-mozillians_url=&user-facebook_url=
+ +

最主要的不同在于URL不再包含任何参数。正如你所见,表单提交的信息被编码后放入消息主体中了。(比如:使用以下命令设置新的用户全名:&user-fullname=Hamish+Willee)

+ +

响应

+ +

请求的响应如下。状态码"302 FOUND"告知浏览器,服务端已收到它提交的post请求,它必须再发出第二个HTTP请求来加载Location字段中指定的页面。对于其他方面的信息含义,则与GET请求的响应信息类似。

+ +
HTTP/1.1 302 FOUND
+Server: Apache
+X-Backend-Server: developer3.webapp.scl3.mozilla.com
+Vary: Cookie
+Vary: Accept-Encoding
+Content-Type: text/html; charset=utf-8
+Date: Wed, 07 Sep 2016 00:38:13 GMT
+Location: https://developer.mozilla.org/en-US/profiles/hamishwillee
+Keep-Alive: timeout=5, max=1000
+Connection: Keep-Alive
+X-Frame-Options: DENY
+X-Cache-Info: not cacheable; request wasn't a GET or HEAD
+Content-Length: 0
+
+ +
+

注意: 上面展示的HTTP请求和响应式通过Fiddler软件来捕获的,你也可以得到相似的信息通过使用网络嗅探器(比如http://web-sniffer.net/)或者使用浏览器扩展例如 HttpFox。你可以自己尝试一下。使用任何一个上面链接的工具,浏览一个站点并修改主要信息来观察不同的请求和响应。更多的现代浏览器拥有网络监控工具(例如,在Firefox上的 Network Monitor 工具)。

+
+ +

静态网站

+ +

静态网站是指每当请求一个特定的资源时,会从服务器返回相同的硬编码内容。因此,例如,如果您在 /static/myproduct1.html 有一个关于产品的页面,则该页面将返回给每个用户。如果您添加另一个类似的产品到您的网站,您将需要添加另一个页面(例如 myproduct2.html )等。这可能开始变得非常低效 :当您访问数千个产品页面时会发生什么——你会在每个页面(基本的页面模板,结构等等)上重复很多代码,如果你想改变页面结构的任何东西,比如添加一个新的“相关产品”部分,必须单独更改每个页面。

+ +
+

注释: 当你有少量页面时,向每个用户发送相同的内容时,静态网站是最佳选择, 然而随着页面数量的增加,它们的维护成本也会很高。

+
+ +

让我们回顾一下在上一篇文章中看到的静态网站架构图,看看它是如何工作的。

+ +

A simplified diagram of a static web server.

+ +

当用户想要导航到页面时,浏览器会发送一个指定HTML页面的URL的HTTP的GET请求。
+ 服务器从它的文件系统中检索所请求的文档,并返回包含文档和HTTP响应状态码“200 OK”(表示成功)的HTTP响应。服务器可能会返回一个不同的状态码,例如,"404 Not Found"表明文件不在服务器上,或者"301 Moved Permanently"表明如果文件存在,则被重定向到另一个位置。

+ +

静态站点的服务器只需要处理 GET 请求,因为服务器不存储任何可修改的数据。它也不会根据HTTP请求数据(例如 URL 参数或 cookie)更改响应。

+ +

了解静态站点如何工作在学习服务器端编程时非常有用,因为动态站点以完全相同的方式处理对静态文件(CSS、JavaScript、静态图像等)的请求。

+ +

动态网站

+ +

动态站点可以根据特定的请求 URL 和数据生成和返回内容(而不是总是返回同一个URL的硬编码文件)。使用产品网页的示例,服务器将把产品“数据”存储在数据库中,而不是单独的HTML文件。当接收到一个产品的HTTP GET 请求时,服务器将确定产品 ID,从数据库中获取数据,然后通过将数据插入到HTML模板中来构造响应的HTML页面。与静态站点相比,这有很大的优势

+ +

通过使用数据库,可以有效地将产品信息存储在易于扩展、可修改和可搜索的方式中。

+ +

使用 HTML 模板可以很容易地改变HTML结构,因为这只需要在一个模板中的某一处地方完成,而不需要跨越数千个静态页面。

+ +

剖析动态请求

+ +

本节将逐步概述“动态” HTTP 请求和响应周期,以更详细的内容构建我们在上一篇文章中所看到的内容。为了“让事情保持真实”,我们将使用一个体育团队经理网站的情景,在这个网站上,教练可以用 HTML 表单选择他们的球队名称和球队规模,并为他们的下一场比赛中获得建议的“最佳阵容”。

+ +

下面的图表显示了“球队教练”网站的主要元素,以及当教练访问他们的“最佳团队”列表时,操作序列的编号。使其动态的站点的部分是 Web 应用程序(这就是我们将如何引用处理 HTTP 请求并返回 HTTP 响应的服务器端代码)数据库,该数据库包含关于球员、球队、教练及其关系以及HTML 模板的信息。

+ +

This is a diagram of a simple web server with step numbers for each of step of the client-server interaction.

+ +

在教练提交球员名单和球员人数后,其操作顺序为:

+ +
    +
  1. Web 浏览器使用资源的基本 URL(/best)来创建一个HTTP GET请求,将球队和球员编号附加到URL后面作为参数(例如 /best?team = my_team_name&show = 11)或作为URL地址的一部分(例如 /best/my_team_name/11/)。使用GET请求是因为请求只是获取数据(而不是修改数据)。
  2. +
  3. Web 服务器检测到请求是“动态的”,并将其转发给 Web 应用程序(Web Application)进行处理( Web 服务器根据其配置中定义的模式匹配规则确定如何处理不同的 URL )。
  4. +
  5. Web 应用程序(Web Application)确定请求的意图是根据 URL(/best/)获得“最佳团队列表”,并从 URL 中找出所需的球队名称和球员人数。然后,Web 应用程序(Web Application)从数据库中获取所需的信息(使用额外的“内部”参数来定义哪些球员是“最好”的,并且可能还从客户端 cookie 获得登录教练的身份)。
  6. +
  7. Web应用程序(Web Application)通过将数据(来自数据库)放入 HTML 模板中的占位符中动态地创建 HTML页面。
  8. +
  9. Web应用程序(Web Application)将生成的HTML(通过Web服务器)和HTTP状态代码200(“成功”)返回到Web浏览器。如果有任何东西阻止HTML被返回,那么Web应用程序将返回另一个状态代码 - 例如“404”来表示球队不存在。
  10. +
  11. 然后,Web 浏览器将开始处理返回的 HTML ,发送单独的请求以获取其引用的任何其他 CSS 或 JavaScript 文件(请参阅步骤7)。
  12. +
  13. Web 服务器从文件系统加载静态文件,并直接返回到浏览器(同样,正确的文件处理基于配置规则和URL模式匹配)。
  14. +
+ +

在服务器中,更新数据库中的记录的操作将被类似地与上述过程一样处理,但是更新数据库的这一类的操作,应该指定来自浏览器的HTTP请求为POST请求。

+ +

完成其他工作

+ +

Web 应用程序(Web Application)的工作是接收 HTTP 请求并返回 HTTP 响应。虽然与数据库交互以获取或更新信息是非常常见的功能,但是代码也可能同时做其他事情,甚至不与数据库交互。
+
+ 一个 Web 应用程序(Web Application)可能执行的额外任务的一个很好的例子就是发送一封电子邮件给用户,以确认他们在网站上的注册。该网站也可能执行日志记录或其他操作。

+ +

返回HTML以外的内容

+ +

服务器端网站代码并非只能在响应中返回 HTML 代码片段/文件。它可以动态地创建和返回其他类型的文件(text,PDF,CSV 等)甚至是数据(JSON,XML等)。
+
+ 将数据返回到 Web 浏览器以便它可以动态更新自己的内容(AJAX)的想法实现已经有相当长的一段时间了。最近,“单页面应用程序”已经变得流行起来,整个网站用一个 HTML 文件编写,在需要时动态更新。使用这种风格的应用程序创建的网站将大量的计算成本从服务器推向网络浏览器,并可能导致网站表现出更像本地应用程序(高度响应等)。

+ +

web框架简化服务器端的web编程

+ +

服务器端web框架使得编写解决我们上面描述的操作的代码变得简单得多。

+ +

web 框架可以提供的一个最重要的功能就是,提供简单的机制,以将不同的资源和页面定位到具体的处理函数。这使得保持代码和各个不同形式的资源的联系变得简单。它也非常利于代码的维护,因为你可以直接改变在一个地方用来传输特定功能的URL,而不用改变处理函数。

+ +

举个例子,我们来思考一下下面的 Django(python) 代码,这些代码将两个 URL 地址定位到两个页面。第一个地址确保了,一个包含了 /best/ URL 的 HTTP 请求,可以被传递到一个在views模块的被命名为index()的函数。一个含有"/best/junior"的请求则会被传递到junior()视图函数。

+ +
# file: best/urls.py
+#
+
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+    # example: /best/
+    url(r'^$', views.index),
+    # example: /best/junior/
+    url(r'^junior/$', views.junior),
+]
+ +
+

注意: 在url()函数中的第一个参数可能看起来有点古怪 (比如r'^junior/$)  因为他们使用一个叫做“正则表达式”(RegEx, or RE)的字符匹配机制。在这里,你还不需要知道正则表达式是如何工作的,除了要知道它们是如何允许我们在URL中匹配到字符的 (而不是像上面的硬编码) 并且知道如何在我们的视图函数中将它们用作参数。举个例子,一个真正简单的正则表达式可能会说“匹配一个大写字母,后面跟着4到7个小写字母”"

+
+ +

Web 框架还可以轻松地使用查看函数,从数据库获取信息。我们的数据结构是在模型中定义的,模型是定义要存储在底层数据库中的字段的Python类。如果我们有一个名为Team的模型,其中有一个“team_type”字段,那么我们可以使用一个简单的查询语法来取回所有具有特定类型的球队。

+ +

下面的例子得到了所有字段team_type(区分大小写)为“junior”的所有球队的列表 - 注意格式:字段名称(team_type),后面跟着双下划线,然后是使用的匹配类型)。还有很多其他的匹配类型,我们可以组合他们。我们也可以控制返回结果的顺序和数量。

+ +
#best/views.py
+
+from django.shortcuts import render
+
+from .models import Team
+
+
+def junior(request):
+    list_teams = Team.objects.filter(team_type__exact="junior")
+    context = {'list': list_teams}
+    return render(request, 'best/index.html', context)
+
+ +

junior()函数获得少年组列表后,它调用render()函数,传递原始的HttpRequest,一个HTML模板和一个定义要包含在模板中的信息的“context”对象。 render()函数是一个方便的函数,它使用上下文和HTML模板生成 HTML,并将其返回到 HttpResponse 对象中

+ +

显然地 web 框架可以帮助你解决很多问题。我们在下一篇文章里将会大量讨论这些好处和一些流行的web框架。

+ +

总结

+ +

到这里你应该对于服务器端代码不得不进行的操作有一个整体上的理解,并且知道一个服务器端web框架是从那些方面让这些变得更简单的。

+ +

在接下来的模块里面我们会帮助你选择对于你的第一个网站来说最适合的web框架。

+ +

{{PreviousMenuNext("Learn/Server-side/First_steps/Introduction", "Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}

diff --git a/files/zh-cn/learn/server-side/first_steps/index.html b/files/zh-cn/learn/server-side/first_steps/index.html new file mode 100644 index 0000000000..c047603f72 --- /dev/null +++ b/files/zh-cn/learn/server-side/first_steps/index.html @@ -0,0 +1,46 @@ +--- +title: 服务端网站编程的第一步 +slug: learn/Server-side/First_steps +tags: + - 初学者 + - 学习 + - 服务端编程 + - 脚本编程 +translation_of: Learn/Server-side/First_steps +--- +
{{LearnSidebar}}
+ +
在我们的服务端编程板块中,我们回答了服务端编程的一系列基础问题—“它是什么?”,“它和客户端编程的区别是什么?”,还有“为什么它是有价值的?”。然后我们提供了对几个最受欢迎的服务端Web框架的概览,同时还有对如何选择最适合的框架来创建你第一个网站的指导。最后我们提供了一篇从高层次介绍Web服务器安全的文章。
+ +
+ +

先决条件

+ +

在开始这个模块之前,你不必知道任何关于服务端网站编程的知识,或者任何一种其他编程经验。

+ +

你需要先知道“Web如何工作”,我们推荐你首先阅读下面几个话题:

+ + + +

有了这些基础知识,你已经准备好开始这些模块的学习了。

+ +

引导

+ +
+
服务端简介
+
欢迎来到MDN提供的初学者服务端编程课程!在我们第一篇文章中,我们从一个很高的角度来审视服务端编程,回答的问题都是类似于:什么是服务端编程?它与客户端编程的区别在哪?以及为什么它如此有价值?在阅读本文之后,你将通过服务端编程了解更多关于网站开发的知识。
+
客户端编程回顾
+
现在你应该了解服务端编程的目的以及它可能带来的好处,我们现在要去探究一些细节,当服务端接收到浏览器的“动态请求”时,到底发生了什么。大多数服务端代码都是用相似的方式来处理请求以及应答,这一点将帮助你更好地明白在编写你自己的代码时,你到底需要做些什么。
+
服务端web框架
+
最后一篇文章将会介绍当服务端web程序为了响应web浏览器发出的请求,它需要做些什么。现在我们来看看web框架是如何简化这些任务的,除此之外,本文还将帮助你为你自己的第一个服务端web程序选择一个合适的框架。
+
网站安全性
+
在网站的设计与使用过程中,网站安全在方方面面都需要引起警惕。这篇引导性的文章不会让你成为网站安全方面的专家,但是它能够帮你了解为了强化你的web应用用以抵抗大多数常见的威胁时,你应该做的第一件重要的事是什么。
+
+ +

评估

+ +

这块“概览性”的内容并不会有任何评估练习,因为我们至今还没向你展示一句代码。我们确切地希望到了这里,你已经对服务端编程提供的各种功能有了一个很好的理解,并且已经为创建你自己的第一个web站点选好了合适的web框架。

diff --git a/files/zh-cn/learn/server-side/first_steps/introduction/index.html b/files/zh-cn/learn/server-side/first_steps/introduction/index.html new file mode 100644 index 0000000000..7f6a05f4e0 --- /dev/null +++ b/files/zh-cn/learn/server-side/first_steps/introduction/index.html @@ -0,0 +1,239 @@ +--- +title: 服务端编程介绍 +slug: learn/Server-side/First_steps/Introduction +tags: + - 介绍 + - 初学者 + - 向导 + - 学习 + - 服务 + - 服务器端编程 + - 服务端编程 +translation_of: Learn/Server-side/First_steps/Introduction +--- +
+
+ +
{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}
+
+ +

欢迎来到MDN为初学者准备的服务器端编程课程!在第一篇文章里面我们将会从一个较高的角度来看待服务器端编程,通过解答下面这些问题来实现这一点,比如:服务器端编程是什么?服务器端编程和客户端编程有何不同?还有,为什么服务器端编程这么有用?当你读完这篇文章后,你会理解通过服务器端编程实现的网站所能提供的额外的功能。

+ + + + + + + + + + + + +
先决条件:基础电脑知识、对“网络服务器是什么”的基本理解
目标:熟悉服务器端编程是什么,它可以做什么,它和客户端编程的区别
+ +

大多数的大型网站采用服务器端编程来在需要的时候动态展示不同的信息,这些信息通常会从服务器上的数据库中取出,然后发送给客户端,并通过一些代码(比如HTML和Javascript)展示在客户端。

+ +

或许服务器端编程的最大益处在于它允许你对不同的用户个体展示不同的网站信息。动态网站可以高亮基于用户喜好和习惯的与用户相关度更高的内容。通过存储用户的偏好设置和个人信息使得网站更加易于使用——比如通过重复使用信用卡的详细信息来简化后续付款流程。

+ +

它允许在页面中与用户进行交互,比如通过邮件或者其他渠道发送通知和更新信息。服务器端的所有的这些能力使得网站可以与用户有更深的联系。

+ +

在现代的web开发中,学习服务器端编程是很被推荐的。

+ +

服务器端编程是什么?

+ +

网络浏览器通过超文本传输协议 ({{glossary("HTTP")}})来和网络服务器 进行通信。当你在网页上点击一个链接,或提交一个表单,再或进行一次搜索时,一个HTTP请求就从你的浏览器发送到了目标服务器。

+ +

这个请求包括一个标识所请求资源的URL,一个定义所需操作的方法(比如获取,删除或者发布资源),还可以包括编码在URL参数中的附加信息。附加信息以键值对(参数和它的值)的形式,通过一个查询字符串,作为POST数据(由HTTP POST方法发送)或存放在与之相关联的{{glossary("Cookie")}}中。

+ +

网络服务器等待客户端的请求信息,在它们到达的时候处理它们,并且回复网络浏览器一个HTTP响应信息。这个响应包含一个表明该请求是否成功的状态行(比如“HTTP/1.1 200 OK”代表请求成功)。

+ +

相应一个请求的成功回应包含被请求的资源(比如一个新的HTML页面,或者图片等),然后这些会被展示在客户端的网络浏览器上。

+ +

静态网站

+ +

下面这张图展示了一个静态网站的基本架构。(静态网站是指无论何时当一个特定资源被请求的时候都返回相同的被硬编码的内容)当用户想要导航到某个页面时,浏览器会发送一个指定到这个页面的URL的HTTP“GET”请求。服务器从它的文件系统中检索被请求的文件,然后返回一个HTTP回应,该回应包括被请求的文件和一个状态码(通常200代表操作成功)。如果出于某些原因被请求的文件无法检索到,就会返回错误码。(具体可以参照客户端错误回应服务器错误回应

+ +

A simplified diagram of a static web server.

+ +

动态网站

+ +

动态网站是指,一些响应内容只有在被需要的时候才会生发的网站。在一个动态网站上,页面通常是通过将数据库的数据植入到HTML模板中的占位符中而产生的(这是一种比使用静态网站有效得多的存储大量内容的方式)。

+ +

动态网站可以基于用户提供的个人信息或者偏好设置来返回不同的数据,并且可以展示作为返回一个回应的内容的一部分的其他操作(比如发送通知)。

+ +

大多数支持动态网站的代码必须运行在服务器上。编写这些代码就是所谓的“服务器端编程”(有些时候也称“后端脚本编写”)。

+ +

下面的图表展示了一个动态网站的简单架构。就像之前的图表那样,浏览器发送HTTP请求给服务器,然后服务器处理请求并且返回合适的HTTP响应。

+ +

动态网站对于静态资源的请求的处理方式和静态网站是一样的(静态资源是指那些不会改变的文件——最典型的就是:CSS,Javascript,图片,预先生成的PDF文件等)。

+ +

A simplified diagram of a web server that uses server-side programming to get information from a database and construct HTML from templates. This is the same diagram as is in the Client-Server overview.

+ +

对于动态资源的请求则会指向(2)服务器端代码(在图中显示为Web Application(网络应用))。在处理“动态请求”时,服务器会首先解释请求,从数据库中读取被请求的信息,然后将这些被检索的信息组合到HTML模板中(4),最后返回一个包含所生成的HTML页面的回应(5,6)。

+ +
+

服务器端编程和客户端编程是一样的吗?

+
+ +

让我们将注意力转向涉及服务器端编程和客户端编程的代码。在每一个情况下,代码都是显然不同的:

+ + + +

在浏览器端运行的代码被称为客户端代码,并且主要涉及所呈现的网页的外观和行为的改进。这就包括选择和设计UI元素、布局、导航、表单验证等。相反的,服务器端网站编程主要涉及,对于相应的请求,选择所要返回给浏览器的内容。服务器端代码解决这样一些问题,比如验证提交的数据和请求、使用数据库来存储和检索信息及发送给用户正如他们所请求的的正确内容。

+ +

客户端代码使用 HTMLCSS,和JavaScript 来编写——这些代码直接在网络浏览器中运行,并且几乎没有访问底层操作系统的路径(包括对文件系统访问的限制)。

+ +

web开发者无法控制用户可能会使用哪一种浏览器来浏览网站——浏览器对客户端代码的兼容性支持水平不一致,客户端编程的一部分挑战就是如何优雅地处理浏览器兼容性问题。

+ +

服务器端代码可以用任何一种编程语言进行编写——比较受欢迎的服务器端编程语言包括PHP、Python、Ruby和C#。服务器端代码有充分的权限访问服务器的操作系统,并且开发者可以选择他们希望使用的编程语言(和特定版本的语言)。

+ +

开发者们通常会使用web框架来编写他们的代码。web框架是一个各种函数、对象、方法和其他代码结构的集合体,web框架被设计用来解决一些普遍问题,从而加速开发,并且简化在一个特定领域中面临的不同类型的任务。

+ +

同样的,当客户端和服务器端代码使用框架时,它们的领域是不同的,因此框架也会不同。客户端web框架简化布局和演示任务,然而服务器端web框架提供大量的普通网络服务功能,不然的话你可能需要自己来实现这些功能(比如支持会话、支持用户和身份验证、简单的数据访问、模板库等)。

+ +
+

注意事项:客户端框架通常被用来帮助加速客户端代码的开发,但是你也可以选择手写所有的代码;事实上,如果你只需要一个小型的、简单的网站UI,手写自己的代码可能更快并且更高效。

+ +

相反的,你应该从来没有考虑过不使用框架而直接编写web应用程序的服务器端组件——实现一个重要的功能比如HTTP服务器真的很难直接从头开始用Python语言构建,但是一些用Python语言写的web框架,比如Django提供了开箱即用的功能,同时还包含其他很多有用的工具。

+
+ +
+

你可以在服务器端做什么?

+ +

服务器端编程是非常有用的,因为它允许我们高效地分发为个人用户制定的信息,从而创造了更佳的用户体验。

+
+ +

一些公司比如亚马逊使用服务器端编程来生成产品的搜索结果、根据客户的偏好和过去的购买习惯来推荐目标产品、简化购物流程等。

+ +

银行使用服务器端编程来存储帐号信息,并且仅允许授权的用户查看和进行交易。其他的网络服务,比如Facebook、Twitter、Instagram、和Wikipedia,使用服务器端编程来突出、分享和控制对有趣内容的访问。

+ +

服务器端编程的普遍使用和好处被罗列在了下方。你会发现二者有一些是重叠的!

+ +

信息的高效存储和传输

+ +

想象一下,在亚马逊上提供着多少产品,在脸书上发布了多少帖子?为每一个产品和帖子都创建一个独立的静态页面将是完全不切实际的。

+ +

服务器端网络编程则允许我们在数据库中存储信息,并且允许我们动态地创建和返回HTML和其他类型的文件(比如,PDF文件和图片等)。我们也可以简单地传输数据 ({{glossary("JSON")}}, {{glossary("XML")}}等),来让合适的客户端框架呈现(这样就减少了服务器的处理压力和需要被传输的数据总量)。

+ +

服务器的工作内容不仅限于从数据库发送信息,可能还会选择性地返回软件工具的结果,或者来自聊天服务的数据。内容甚至可以被定位到接受它的信息的客户端设备的类型。

+ +

因为数据被放在数据库中,因此更加容易被分享和更新到其他商业系统(比如,当产品在网上或者实体店卖掉之后,商店可以更新它的存货清单数据库)

+ +
+

注意:你不用很难就可以想到服务器端代码对于高效存储和传输信息的好处:

+ +
    +
  1. 打开亚马逊或者其他一些电子商务网站。
  2. +
  3. 搜索一系列关键词,然后注意到页面结构并没有发生改变,尽管搜索结果发生了改变。
  4. +
  5. 打开两到三个不同的产品。注意到它们是如何拥有一个相似的结构和布局的,但是不同产品的内容是从不同数据库中获取的。
  6. +
+ +

对于一个普通的搜索词条(比如“鱼”),你会看到数百万的返回值。使用数据库允许这些数据被高效地存储和分享,并且使得信息的展示就被控制在那一个特定的地方。

+
+ +

定制用户体验

+ +

服务器可以存储和使用客户的相关信息来提供一个定制化的用户体验。比如,很多网站存储信用卡信息来使得用户不必再次输入细节信息。有些网站,比如,谷歌地图使用家庭或者当前位置来提供路径信息,然后在搜索结果中突出本地商业。

+ +

对用户习惯的更深层分析可以被用来预测用户的兴趣和更加深度地定制化回应和通知,比如,提供一张清单来展示曾经去过的地方,或者在地图上标识你可能想去的非常受欢迎的地点。

+ +
+

注意:谷歌地图会保存你的搜索,浏览的历史记录。频繁地浏览或者频繁地搜索地址将会使得它更加的醒目。

+ +

谷歌搜索结果基于之前的搜索进行优化。

+ +

1.访问谷歌搜索

+ +

2.搜索 “足球”

+ +

3.现在在搜索框中输入 “喜欢” ,你就会观察到搜索会自动补全

+ +

真的是巧合嘛?这算不上什么!

+
+ +

控制对内容的访问

+ +

服务器端编程允许网站限制合法用户的权限,并且只提供用户被允许查看的信息。

+ +

真实世界的例子有:

+ + + +
+

注意:想想其他真实的限制了内容访问例子。比如,如果你直接访问你银行的网页,你可以看到什么?用你的帐号登录之后——你可以看到和修改什么额外的信息呢?有些什么信息是你只可以看到的而只有银行可以修改的?

+
+ +

存储会话和状态信息

+ +

服务器端编程允许开发者们充分利用会话——简单来说就是一种机制,这种机制允许服务器存储一个网站现有用户信息,并且基于那些信息发送不同响应。

+ +

这也就允许,比如说,一个网站知道一个用户曾经登录过并且展示他们邮箱的链接或者订单历史,或者可能存储一个简单游戏的状态来确保用户可以再次访问网站然后从上次留下来的地方继续。

+ +
+

注意:访问一个具有订阅模式的新闻网站,并且打开一系列标签(比如The Age)。几个小时或者几天之后再来访问这个网站。最后你将开始被重定向到一个向你解释如何订阅的页面上,并且你将无法访问文章。这个信息就是一个session信息被存储在cookie中的例子

+
+ +

通知和通讯

+ +

服务器可以发送面向全体的或者面向指定用户的通知,通过网站自身或者通过邮箱、SMS、即时消息、视频会话或者其他的通讯服务。

+ +

几个例子:

+ + + +
+

注意:最普通的一种通知类型就是“注册认证”。选择任何一个你感兴趣的大型网站(谷歌、亚马逊、Instagram等)并且用你的邮箱创建一个新的帐号。你很快会收到一封验证你的注册的邮件,或者需要你去激活帐号。

+
+ +

数据分析

+ +

一个网站可以收集到有关用户的大量的信息:他们搜索什么?他们买什么?他们分享什么?他们在每一个页面停留多久?服务器端编程可以被用来基于这些数据的分析而细化回应。

+ +

比如,亚马逊和谷歌都基于过去的搜索(和购物)信息来为产品打广告。

+ +
+

注意:如果你使用Facebook,去看看你的main feed,然后看一下帖子流。注意到其中一些帖子不是按照数字进行排列的-拥有更多“喜欢”的帖子在列表中通常高于最近的帖子。

+ +

也可以看一下你收到的广告是什么类型的——你或许会看到你在其他网站查看的商品。Facebook为突出内容和广告的算法或许还很令人疑惑,但是很明显的,它是依据你的喜好、品味和习惯的!

+
+ +

总结

+ +

恭喜,你已经看到了第一篇有关服务器端编程的文章的结尾处。

+ +

你已经了解到的就是,服务器端代码在服务器上运行,它的主要角色是控制什么信息应该发送给用户(然而客户端代码只要解决给用户的数据的结构和展示)。

+ +

你也应该理解服务器端代码是非常有用的,因为它允许我们创建,可以高效地向个体用户传输定制化的信息的,网站。另外,你还应该知道当你是一个服务器端程序员时可能能够做的一些事情。

+ +

最后你应该理解服务器端代码可以用很多种编程语言进行编写,并且你应该使用一个web框架来使得这个过程更加容易一点。

+ +

在接下来的文章中我们会帮助你选择一个对于你的第一个网站来说最好的web框架;但是,再接下来我们稍微详细一点地带你过一遍主要的客户端-服务器交互行为。

+ +

{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}

+ +

在这个模块中

+ + diff --git a/files/zh-cn/learn/server-side/first_steps/web_frameworks/index.html b/files/zh-cn/learn/server-side/first_steps/web_frameworks/index.html new file mode 100644 index 0000000000..47b23da420 --- /dev/null +++ b/files/zh-cn/learn/server-side/first_steps/web_frameworks/index.html @@ -0,0 +1,298 @@ +--- +title: 服务端web框架 +slug: learn/Server-side/First_steps/Web_frameworks +tags: + - web框架 + - 介绍 + - 初学者 + - 学习 + - 指导 + - 服务器 + - 服务器端编程 + - 编码 +translation_of: Learn/Server-side/First_steps/Web_frameworks +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps/Website_security", "Learn/Server-side/First_steps")}}
+ +

前面的文章向你展示了web客户端和服务器之间的通信是什么样子的,HTTP的请求和回应之间的性质,以及服务器端应用为了回应来自web浏览器的请求的需要做的事情。有了这些知识后,现在是时候来探索一个web框架是如何简化这些任务的,并且告诉你应该如何为你的第一个服务器端应用选择一个框架。

+ + + + + + + + + + + + +
预先要求:基础电脑素养。对于服务器端代码是如何处理并响应HTTP请求有深刻的理解。(参见Client-Server overview
目标:理解web框架是如何简化服务器端代码的开发和维护的,并且帮助读者思考如何为他们自己的开发项目选择一个框架。
+ +

下面的部分通过使用一些来自web框架的代码段来说明一些要点。如果不能完全看懂代码也不用太在意。我们在“框架详解”模块会帮助你完全理解。

+ +

概览

+ +

服务器端框架(亦称 "web 应用框架") 使编写、维护和扩展web应用更加容易。它们提供工具和库来实现简单、常见的开发任务, 包括 路由处理, 数据库交互, 会话支持和用户验证, 格式化输出 (e.g. HTML, JSON, XML), 提高安全性应对网络攻击.

+ +

下一节将详细介绍web框架如何简化web应用程序开发。然后,我将阐述一些选择web框架的标准,并给你列出一些选项。

+ +

web框架可以为你做什么?

+ +

你并不是必须得使用一个服务器端的web框架,但是我们强烈建议你使用框架——框架会使得你的生活更美好。

+ +

这个部分我们讲一下web框架通常会提供的功能(并不是说每一个框架一定会提供下面的所有功能!)

+ +

直接处理 HTTP 请求和响应

+ +

从上一篇文章中我们知道,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')
+
+ +

将请求路由到相关的handler中

+ +

大多数的站点会提供一系列不同资源,通过特定的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框架(我们在下面的部分列举了一些比较受欢迎的框架)。有这么多选择,导致很难决定选择哪个框架为你的新web应用提供最好的开端。

+ +

一些影响你决定的因素有:

+ + + +

可能还有其他一些原因,包括许可证、框架是否处于动态发展过程中等等。

+ +

如果你是一个完全的初学者,那么你可能会基于“易于学习”来选择你的框架。除了语言本身的“易于学习”之外,帮助新手的高质量的文档/教程和一个活跃的社区是你最有价值的资源。在后续课程中,我们选取了Djnago(Python)和Express(Node/Javascript)来编写我们的实例,主要因为它们很容易上手并且有强大的支持。

+ +
+

注意: 我们可以去 Django (Python) 和 Express (Node/JavaScript) 的主页上去看看它们的文档和社区。

+ +
    +
  1. 导航至主页 (上面已给出链接) +
      +
    • 点击文档菜单的链接 (通常都叫做 "Documentation(文档), Guide(指南), API Reference(API参考), Getting Started(快速开始)"之类的。)
    • +
    • 你能看到如何设置URL路由、模板、数据库/数据模型的主题吗?
    • +
    • 文档说得够清楚吗?
    • +
    +
  2. +
  3. 导航至各个站点的邮件列表(从社区的链接访问) +
      +
    • 近几天提出了多少问题?
    • +
    • 有多少问题得到了回应?
    • +
    • 他们是否有一个活跃的社区?
    • +
    +
  4. +
+
+ +

几个还不错的框架?

+ +

让我们继续,来讨论几个特定的服务器端框架。

+ +

下面的服务器端框架体现了现在最受欢迎的几个。它们有你需要用来提升效率的一切东西——它们是开源的,一直保持发展的态势,有着富有激情的社区,社区里的人创作出文档并且在讨论板上帮助使用者,并且被使用在很多高质量的网站上。当然还有很多其他非常棒的框架,你可以使用搜索引擎探索一下。

+ +
+

注意:(部分)解释来自框架的官方网站!

+
+ +

Django (Python)

+ +

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是python的一个微型框架

+ +

虽然体量很小,Flask却可以开箱即用地创造出完备网站。它包含一个开发服务器和调试器,并且包含对于 Jinja2 模板的支持, 安全的cookie, unit testing, 和 RESTful request dispatching。它有很好的文档和一个活跃的社区。

+ +

Flask已经非常火爆了,部分因为那些需要在小型的、资源受限的系统中提供web服务的开发者们。(比如,在Raspberry Pi, Drone controllers等上面运行服务器)。

+ +

Express (Node.js/JavaScript)

+ +

Express 针对 Node.js 的快速的、unopinioned、灵活的、小型的web框架(node是用来运行Javascript的无浏览器的环境)。它为web和移动应用提供强大的系列功能,并且传输有用的HTTP工具、方法和middleware.

+ +

Express非常受欢迎,主要因为它减轻了客户端Javascript程序到服务器端开发的迁移,并且部分因为它是资源节约型(底层的node环境在单线程中使用轻量级多任务处理,而不是为每个web请求提供单独的进程)。

+ +

因为Express是一个小型的web框架,它几乎不包含任何你可能想要使用的组件(比如,数据库接口和对用户和会话的支持通过独立的库来完成)。有很多独立的、非常好的组件,但是有时候你可能很难决定对于特定目的而言哪一个是最好的! 

+ +

 很多非常受欢迎的服务器端编程和全栈框架(同时包括服务器端和客户端框架),包括 FeathersItemsAPIKeystoneJSKrakenLEAN-STACKLoopBackMEAN, 和 Sails.

+ +

大量的profile company使用Express,包括优步、Accenture、IBM等(这里是一张列表).

+ +

Ruby on Rails (Ruby)

+ +

Rails (通常被称作"Ruby on Rails")是一个为Ruby语言编写的web框架。

+ +

Rails遵循了和Django非常相似的设计哲学。正如Django一样,它提供了检索URLs的标准机制、从数据库中访问数据、从模板中生成HTML页面、格式化数据{{glossary("JSON")}} 或者 {{glossary("XML")}}。同样的,它也鼓励如 DRY (不要重复你自己)的设计模板——尽可能地只写一次代码、MVC(模板-视图-控制中心)以及很多其他的一些。

+ +

当然,还有很多由于因为具体设计决定和语言的特性导致的差异。

+ +

Rails被用在很多站点中,包括: BasecampGitHub,ShopifyAirbnbTwitchSoundCloud,HuluZendeskSquareHi

+ +

ASP.NET

+ +

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)

+ +

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")}}

diff --git a/files/zh-cn/learn/server-side/first_steps/website_security/index.html b/files/zh-cn/learn/server-side/first_steps/website_security/index.html new file mode 100644 index 0000000000..3b6e400257 --- /dev/null +++ b/files/zh-cn/learn/server-side/first_steps/website_security/index.html @@ -0,0 +1,165 @@ +--- +title: 站点安全 +slug: learn/Server-side/First_steps/Website_security +tags: + - 安全 + - 站点安全 +translation_of: Learn/Server-side/First_steps/Website_security +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}
+ +

站点安全需要在网站设计和使用的各个方面保持警惕。这篇入门文章不会让你成为一个网站安全专家,但是可以帮助你理解威胁的来源以及如何保护你的Web应用来远离这些常见的攻击。

+ + + + + + + + + + + + +
准备内容:计算机基础知识.
目标: +

了解针对Web应用常见的攻击方式和用来减少网站被黑客攻击的风险的方法。

+
+ +

什么是站点安全?

+ +

互联网很危险!我们经常听到网站因为拒绝服务攻击或主页显示被修改的(通常是有害的)内容而无法使用。在一些出名的案例中,上百万的密码、邮件地址和信用卡信息被泄露给了公众,导致网站用户面临个人尴尬和财务威胁。

+ +

站点安全的目的就是为了防范这些(或者说所有)形式的攻击。更正式点说,站点安全就是为保护站点不受未授权的访问、使用、修改和破坏而采取的行为或实践。

+ +

有效的站点安全需要在对整个站点进行设计:包括Web应用编写、Web服务器的配置、密码创建和更新的策略以及客户端代码编写等过程。尽管这听起来很凶险,好消息是如果你使用的是服务器端的Web服务框架,那么多数情况下它默认已经启用了健壮而深思熟虑的措施来防范一些较常见的攻击。其它的攻击手段可以通过站点的Web服务器配置来减轻威胁,例如启用HTTPS. 最后,可以用一些公开可用的漏洞扫描工具来协助发现你是否犯了一些明显的错误。

+ +

文章的剩余部分列举了一些常见威胁的细节以及用来保护站点的一些简单措施。

+ +
+

Note: 这只是一篇介绍性的主题,旨在帮你开始思考站点安全。它并不详尽。

+
+ +

站点安全威胁

+ +

这个部分列举了常见网站攻击手段以及如何减轻它们带来的危害。当你读的时候请注意,这些攻击是如何得手的,当web应用相信这些来自浏览器的信息或者不够坚持自己的时候。

+ +

跨站脚本 (XSS)

+ +

XSS是一个术语,用来描述一类允许攻击者通过网站将客户端脚本代码注入到其他用户的浏览器中的攻击手段。由于注入到浏览器的代码来自站点,其是可信赖的,因此可以做类似将该用户用于站点认证的cookie发送给攻击者的事情。一旦攻击者拿到了这个cookie,他们就可以登陆到站点,就好像他们就是那个用户,可以做任何那个用户能做的事情。根据站点的不同,这些可能包括访问他们的信用卡信息、查看联系人、更改密码等。

+ +
+

Note: XSS 攻击在历史上较其他类型更为常见。

+
+ +

有两种主要的方法可以让站点将注入的脚本返回到浏览器 -- 通常被称做 反射型 和 持久型 XSS攻击。

+ + + +

 防范 XSS 攻击的最好方式就是删除或禁用任何可能包含可运行代码指令的标记。对 HTML 来说,这些包括类似 <script>, <object>, <embed>,和 <link> 的标签。

+ +
+

修改用户数据使其无法用于运行脚本或其它影响服务器代码执行的过程被称作输入过滤。许多Web框架默认情况下都会对来自HTML表单的用户数据进行过滤。

+
+ +

SQL 注入

+ +

SQL 注入漏洞使得恶意用户能够通过在数据库上执行任意SQL代码,从而允许访问、修改或删除数据,而不管该用户的权限如何。成功的注入攻击可能会伪造身份信息、创建拥有管理员权限的身份、访问服务器上的任意数据甚至破坏/修改数据使其变得无法使用。

+ +

如果传递给底层SQL语句的用户输入可以修改该语句的语义,这种漏洞便是存在的。例如下面一段代码,本来是用来根据HTML表单提供的特定名字(userName)来列出所有的用户:

+ +
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
+ +

如果用户输入了真实的名字,这段代码会如预想的运行。然而一个恶意用户可以完全将这个SQL语句的行为改变为下面的新语句的行为,只要通过将 userName指定为下列 “粗体” 的文本。修改后的代码创建了一个合法的SQL语句,该语句删除了整个 users 表,然后从 userinfo 表中获取了所有数据(所有用户的信息都被暴露了)。这是有效的,因为注入的文本的第一部分(a';)结束了原来的语句( ' 在SQL语句中是用来描述字符串常量的) 。

+ +
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
+
+ +

避免此种攻击的方法就是确保任何传递给SQL查询语句的用户数据都无法更改查询的本来用意。有种方式便是将用户输入中任何在SQL语句中有特殊含义的字符进行转义。

+ +
+

Note: SQL语句把 ' 号作为一个字符串常量的开头的结尾。通过在前面放置一个斜杠,我们把单引号进行了转义( \' ),然后 SQL 就会将其视为一个字符(作为字符串的一部分)。

+
+ +

在下面的语句中我们对 ' 字符进行了转义。SQL会将粗体显示的整段字符串解释为 name(这个name很古怪,但至少是没有危害的!)

+ +
SELECT * FROM users WHERE name = 'a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t';
+
+
+ +

Web框架通常会为你进行这种转义操作。例如 Django,可以确保任何传递给查询集合 (model查询)的用户数据都是已经转义过的。

+ +
+

Note: 本章节引用了大量来自 Wikipedia 的内容.

+
+ +

跨站请求伪造 (CSRF)

+ +

CSRF 攻击允许恶意用户在另一个用户不知情的情况下利用其身份信息执行操作。

+ +

这种形式的攻击用实例来解释最好。John是一个恶意用户,他知道某个网站允许已登陆用户使用包含了账户名和数额的HTTP POST请求来转帐给指定的账户。John 构造了包含他的银行卡信息和某个数额做为隐藏表单项的表单,然后通过Email发送给了其它的站点用户(还有一个伪装成到 “快速致富”网站的链接的提交按钮).

+ +

如果某个用户点击了提交按钮,一个 HTTP POST 请求就会发送给服务器,该请求中包含了交易信息以及浏览器中与该站点关联的所有客户端cookie(将相关联的站点cookie信息附加发送是正常的浏览器行为) 。服务器会检查这些cookie,以判断对应的用户是否已登陆且有权限进行上述交易。

+ +

最终的结果就是任何已登陆到站点的用户在点击了提交按钮后都会进行这个交易。John发财啦!

+ +
+

Note: 这里的诀窍是,John 不需要访问那些用户的cookie(或者说身份信息) -- 用户的浏览器存储了这些信息,而且会自动将其包含在发送给对应服务器的请求中。

+
+ +

杜绝此类攻击的一种方式是在服务器端要求每个 POST 请求都包含一个用户特定的由站点生成的密钥( 这个密钥值可以由服务器在发送用来传输数据的网页表单时提供)。这种方式可以使John无法创建自己的表单,因为他必须知道服务器提供给那个用户的密钥值。即使他找出了那个密钥值,并为那个用户创建了表单,他也无法用同样的表单来攻击其他的所有用户。

+ +

Web 框架通常都会包含一些类似的CSRF 防范技巧。

+ +

其他威胁

+ +

其它常见的攻击/漏洞利用方式包括:

+ + + +

还有很多的方式。要查看更全面的列表,请访问 Category:Web security exploits (Wikipedia) 和 Category:Attack (Open Web Application Security Project).

+ +

一些关键信息

+ +

当Web应用信任来自浏览器的数据时,上述章节里提到的大多数攻击利用手段才能成功。无论你做什么其它的事情来提升你的网站的安全性能,在将信息展示在浏览器之前、在使用SQL语句进行查询之前、在传递给一个操作系统或者文件系统之前,你应该过滤掉所有的用户源信息。

+ +
+

重要:在你可以了解到的有关网站安全大多数 课程之中,最重要的就是不要相信来自浏览器的数据。包括在URL参数中的GET请求、POST请求、HTTP头、cookies、用户上传的文件等等。一定要每次都检查用户输入的信息。每次都预想最坏的结果。

+
+ +

你可以采取一些简单的步骤:

+ + + +

web框架可以帮助抵御很多常见的攻击。

+ +

总结

+ +

这篇文章介绍了有关网络安全的概念和你应该避免的一些常见的攻击。最重要的是,你应该明白一个web应用不可以相信任何来自网络服务器的数据!所有的用户数据在展示、使用SQL查询或者回应系统之前应该被过滤。

+ +

这也是这个模块的结尾,涵盖了你之前在服务器端编程学到的知识。我们希望你非常享受这个学习基础概念的过程,并且你现在已经准备好选择一个web框架开始编程了。

+ +

{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}

-- cgit v1.2.3-54-g00ecf