WSGI和CGI是什么?请用通俗易懂的语言解释。

147
每次我读到WSGI或CGI时都会感到不舒服。我之前尝试过阅读相关内容,但并没有真正了解到它的含义。
简单来说,它们是处理Web服务器和Python应用程序之间通信的协议。它们允许Python应用程序接收来自Web服务器的请求,并将响应发送回Web服务器以供显示。它们并不仅仅是将请求导向终端并重定向输出。

3
https://dev59.com/oHVC5IYBdhLWcg3wqzHV - Josh Lee
4个回答

281

从完全超然的角度来看,Blankman,这是我为Web服务器网关接口准备的“介绍页面”:

第一部分:WEB服务器

Web服务器提供响应。它们静静地坐着,等待着,然后突然间:

  • 客户端进程发送请求。客户端进程可以是Web服务器、机器人、移动应用程序等。“客户端”只是一个名称。
  • Web服务器收到此请求。
  • 刻意的喃喃自语 发生了各种事情(请参见下文)。
  • Web服务器向客户端发送回复。
  • Web服务器再次保持不动。

Web服务器(至少优秀的Web服务器)非常擅长这个。它们根据需求进行缩放处理,可靠地与最不可靠的客户端在真正糟糕的网络上进行会话,我们从未真正担心过它。它们就继续提供服务。

这就是我的观点:Web服务器仅仅是服务器而已。它们对内容、用户或其他东西一无所知,实际上只知道如何长时间等待并可靠地回复。

您选择的Web服务器应反映出您的交付偏好,而不是您的软件。您的Web服务器应负责提供服务,而不是处理或逻辑。

第二部分:(PYTHON)软件

软件不会坐着等待。软件只存在于执行时间。当环境出现意外变化时(文件不在预期位置、参数被重命名等),软件并不十分容易适应。尽管优化应该成为设计的核心原则(当然),但软件本身并不会优化。开发人员才能做到这一点。软件执行所有“刻意的喃喃自语”中的内容。可能是任何东西。

您选择或设计的软件应反映出您的应用程序、您选择的功能,而不是您选择的Web服务器。

这里是传统的将语言“编译到”Web服务器中的方法变得痛苦的地方。您最终会在应用程序中放置代码来处理物理服务器环境,或者至少被迫选择适当的“包装器”库以在运行时包含,以给出跨Web服务器的统一性的错觉。

那么什么是WSGI?

那么,最后,什么是WSGI? WSGI是一组规则,由两个部分编写而成。它们以这样的方式编写,以便可以集成到任何欢迎集成的环境中。

第一部分,编写Web服务器端,说:“好的,如果要处理WSGI应用程序,这是软件在加载时将会考虑的内容。这些是必须提供给应用程序的内容,以及您可以预期每个应用程序具有的接口(布局)。此外,如果发生任何问题,这是应用程序的想法以及您可以期望它如何表现。”

第二部分,编写Python应用程序软件,说:“好的,如果要处理WSGI服务器,这是服务器在联系您时将会考虑的内容。这些是必须提供给服务器的内容,以及您可以预期每个服务器具有的接口(布局)。此外,如果发生任何问题,这是您应该如何行事以及您应该告诉服务器的内容。”

所以,这就是它-服务器将成为服务器,软件将成为软件,这是一种可以在不需要让另一个做出任何特定于另一个的允许的情况下共处的方式。这就是WSGI。

另一方面,mod_wsgi是Apache的插件,使其能够与符合WSGI标准的软件交流,换句话说,mod_wsgi是上述规则中第一部分的一种在Apache中的实现。

至于CGI...问其他人吧 :-)


32
我会尽力进行翻译:与其让这个回答以“去问别人”告终,我希望有人能够以同样的方式编辑此回答,包括CGI。 - Bruno Bronosky
1
服务器就是服务器,软件就是软件。服务器来自火星,软件来自金星 :) - Rahul

70

WSGI在Web服务器启动时运行Python解释器,可以作为Web服务器进程(嵌入式模式)的一部分或作为单独的进程(守护进程模式)来运行,并将脚本加载到其中。每个请求都会调用脚本中的特定函数,并将请求环境作为参数传递给该函数。

CGI在每个请求中将脚本作为单独的进程运行,并使用环境变量、标准输入和标准输出与其“通信”。


21
WSGI 与 mod_wsgi 不同。根据你的语言,你所指的是实现 WSGI 的 mod_wsgi。WSGI 本身仅是一个规范,可以用许多不同的方式来实现,包括在 CGI 之上。 - Graham Dumpleton
@Graham:你是说没有其他支持在这些模式下运行WSGI应用程序的WSGI容器吗? - Ignacio Vazquez-Abrams
4
从技术上讲,可以说除了这两种方式,还有更微妙的变化,至少在嵌入式系统中启动过程或代码激活方面是如此。因此,我们必须小心将事物概括为仅仅这两个类别。从宏观层面上看,你可以这么说,但如果你想深入探讨,实际情况比这要复杂得多。 - Graham Dumpleton
1
@GrahamDumpleton,出于好奇,您介意解释一下如何在CGI的基础上实现WSGI吗? - Mike Lee
3
阅读WSGI规范。其中展示了一个CGI/WSGI桥接的例子。更加稳健的实现请参见https://github.com/GrahamDumpleton/cgi2wsgi。但一般情况下,你应该避免使用CGI。 - Graham Dumpleton
1
2018年9月最新版本的文档:https://docs.python.org/3.4/howto/webservers.html - PirateApp

25

CGI和WSGI都定义了程序可以使用的标准接口来处理Web请求。 CGI接口比WSGI更低级,它涉及到服务器设置包含HTTP请求数据的环境变量,程序返回的内容格式与裸HTTP服务器响应非常相似。

另一方面,WSGI是一个Python特定的,略高级的接口,允许程序员编写与服务器无关并且可以包装在其他WSGI应用程序(中间件)中的应用程序。


25
如果您对这个领域中的所有术语都感到不清楚,那么让我们面对现实,这是一个令人困惑的缩略语。您也可以阅读一个良好的背景阅读材料,即一个官方Python HOWTO,其中讨论了CGI与FastCGI与WSGI等内容。我希望我当初读过它。

该链接包含了我目前为止找到的最详细的解释。然而,它在如何在没有WSGI的情况下使用FastCGI方面存在不足,因此未能解释WSGI是什么。除此之外,在MoinMoin之前,它真的很棒,但又一次未能解释WSGI与FastCGI接口相比的真正含义。此外,当尝试在没有WSGI模型的情况下进行开发时,我的问题仍然存在,即mod_python、fastcgi是否都使用传统的CGI接口。此外,即使是在CGI中,它也没有真正解释通过stdin、stdout、env等方式如何与CGI程序通信。 - huggie
阅读维基百科上的CGIPEP3333条目可以澄清很多事情。 - huggie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接