服务端编程介绍

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

前提: 基础电脑知识、对“Web 服务器是什么”的基本理解
目标: 熟悉服务器端编程是什么,它可以做什么,它和客户端编程的区别

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

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

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

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

服务器端编程是什么?

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

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

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

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

静态网站

下面这张图展示了一个静态网站的基本架构。(静态网站是指无论何时当一个特定资源被请求的时候都返回相同的被硬编码的内容)当用户想要导航到某个页面时,浏览器会发送一个指定到这个页面的 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(Web 应用))。在处理“动态请求”时,服务器会首先解释请求,从数据库中读取被请求的信息,然后将这些被检索的信息组合到 HTML 模板中(4),最后返回一个包含所生成的 HTML 页面的回应(5,6)。

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

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

  • 它们有不同的目的和关注点。
  • 它们通常不会使用相同的编程语言(Javascript 是一个特例,它既可以被用在服务器端也可以被用在客户端)。
  • 它们在不同的操作系统环境中运行。

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

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

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

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

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

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

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

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

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

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

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

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

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

信息的高效存储和传输

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

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

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

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

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

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

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

定制用户体验

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

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

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

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

1.访问谷歌搜索

2.搜索“足球”

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

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

控制对内容的访问

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

真实世界的例子有:

  • 社交网站,比如 Facebook 允许用户完全控制他们自己的数据,但是只允许他们的朋友和家人查看和评论这些数据。用户决定谁可以看到他们的数据,并且通过扩展,决定谁的数据出现在他们的反馈里面——授权是用户体验里面的一个核心部分!
  • 此时此刻你所访问的网站也控制着内容访问:文章对所有人都是可视的,但是只有已经登录的用户可以编辑内容。为了试验一下,你可以点击一下页面上方的编辑按钮——如果你已经登录了的话,将会展示出编辑界面;如果你还没有登录,你会被导航到注册界面。

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

存储会话和状态信息

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

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

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

通知和通讯

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

几个例子:

  • Facebook 和 Twitter 发送邮件或者 SMS 消息来通知你一些新的交谈。
  • 亚马逊定期的向你发送产品邮件并且向你推荐和你曾经买过的产品很相似的产品或者是他们觉得你可能感兴趣的产品。
  • 一个网站的服务器可能向网站管理员发送警告消息来警告他们服务器内存不足或者可疑的用户行为。

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

数据分析

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

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

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

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

总结

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

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

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

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

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