什么是通用网关接口(CGI)?


745

CGI是通用网关接口。顾名思义,它是所有内容的“通用”网关接口。从名称来看,它是如此琐碎而幼稚。我感到自己理解了,每次遇到这个词时都会感到。但坦率地说,我没有。我还是很困惑。

我是一位具有Web开发经验的PHP程序员。

用户(客户端)请求页面---> webserver(->嵌入式PHP解释器)---->服务器端(PHP)脚本---> MySQL服务器。

现在说我的PHP脚本可以从MySQL服务器,MATLAB服务器和其他服务器获取结果。

那么,现在PHP Script是CGI吗?因为它的接口用于Web服务器与所有其他服务器之间?我不知道。有时他们将CGI称为技术,而有时将CGI称为程序或其他服务器。

  • CGI到底是什么?

  • 有什么大不了的/cgi-bin/*.cgi?这是怎么回事?我不知道cgi-bin服务器上的该目录是做什么的。我不知道为什么他们有* .cgi扩展名。

  • 为什么Perl总是妨碍您。CGI和Perl(语言)。我也不知道这两个怎么了。几乎所有时候,我都不断听到“ CGI&Perl”的组合。这本书是使用Perl进行CGI编程的另一个很好的例子。为什么不使用PHP / JSP / ASP进行CGI编程?我从未见过这样的事情。

  • C语言中的CGI编程,让我很困惑。“ 在C中 ”?认真吗?我不知道该说些什么。我很困惑。“ 在C中 ”?这改变了一切。程序需要编译和执行。这完全改变了我对Web编程的看法。我什么时候编译?程序如何执行(因为它将是机器代码,因此必须作为独立的进程执行)。它如何与Web服务器通信?IPC?并使用套接字编程与所有服务器(在我的示例MATLAB&MySQL中)接口?我迷路了!!

  • 人们说CGI已被弃用,不再使用。是这样吗?最新更新是什么?

有一次,我遇到了不得不向Web服务器(Apache HTTPD)授予HTTP PUT请求访问权限的情况。它的后背很长。因此,据我所记得,这就是我所做的:

  1. 编辑了Apache HTTPD的配置文件,以告知Web服务器将所有HTTP PUT请求传递给某些服务器 put.php(我必须编写此PHP脚本)

  2. 实现put.php来处理请求(将文件保存到上述位置)

人们说我写了一个CGI脚本。说真的,我不知道他们在说什么。

  • 我真的写过CGI脚本吗?

希望您理解我的困惑。(因为我自己不知道我在哪里困惑)。我要求你们保持答案尽可能简单。我真的不明白任何花哨的技术术语。至少不是这种情况。

编辑:

我发现了这个很棒的教程“ CGI编程很简单!”。-CGI教程,以最简单的方式解释了这些概念。阅读本文之后,您可能需要阅读《C语言中的CGI编程入门》,以通过实际的代码示例来补充您的理解。我还将这些链接添加到了本教程的Wikipedia文章:http : //en.wikipedia.org/wiki/Common_Gateway_Interface


9
我已经看过用Cobol写的CGI。不要开玩笑!
卢克M 2010年

@Luc M.有兴趣。您指的是哪个CGI(假设LINQ中存在一个射线广播仪...)?

15
@claws:人们(主要是老派)将通过网络服务器将任何代码(无论实际的执行方法如何)称为CGI。您实际编写的是一个PHP脚本,该脚本可能会或可能不会通过CGI协议执行。您的困惑似乎源于CGI的歧义,CGI是一种执行代码的协议,以及通过该协议执行的代码(后来泛化为任何网络执行的代码)
Vinko Vrsalovic,2010年

1
上世纪90年代中期,我在HyperCard中写了一些CGI脚本
Neal Davis

@Joe我从未收到通知,今天,再次阅读这篇文章,我看到了您的问题。CGI是作为独立可执行文件(不涉及框架或第三方应用程序...)在OpenVMS上编写的
Luc M

Answers:


427

CGI是一个告诉Web服务器如何与应用程序之间传递数据的接口。更具体地说,它描述了如何在环境变量(例如请求类型,远程IP地址)中传递请求信息,如何通过标准输入传递请求主体以及如何通过标准输出传递响应。您可以参考CGI规范以获取详细信息。

要使用您的图片:

user (client) request for page ---> webserver ---[CGI]----> Server side Program ---> MySQL Server.

大多数(如果不是全部)网络服务器可以配置为作为“ CGI”执行程序。这意味着网络服务器在收到请求后会将数据转发到特定程序,设置一些环境变量,并通过标准输入和标准输出将参数编组,以便程序可以知道要查找的位置和内容。

主要的好处是,只要Web服务器和程序都知道CGI的工作原理,您就可以从Web运行任何可执行代码。这就是为什么您可以使用启用了CGI的常规Web服务器以C或Bash编写Web程序的原因。这样,并且大多数编程环境都可以轻松使用标准输入,标准输出和环境变量。

在您的情况下,您很可能使用了另一种特定于PHP的脚本和Web服务器之间的通信方式,正如您在问题中所提到的,这是一种称为mod_php的嵌入式解释器。

因此,回答您的问题:

CGI到底是什么?

往上看。

/cgi-bin/*.cgi有什么大不了的?这是怎么回事?我不知道服务器上的cgi-bin目录是做什么的。我不知道为什么他们有* .cgi扩展名。

那是CGI程序的传统场所,许多Web服务器都预先配置了此目录,以将所有二进制文件作为CGI程序执行。.cgi扩展名表示期望通过CGI工作的可执行文件。

为什么Perl总是妨碍您。CGI和Perl(语言)。我也不知道这两个怎么了。几乎所有时候,我都不断听到“ CGI&Perl”的组合。本书是使用Perl进行CGI编程的另一个很好的例子,为什么不使用“使用PHP / JSP / ASP进行CGI编程”。我从未见过这样的事情。

因为Perl很古老(比CGI早就诞生的PHP,JSP和ASP都古老,所以Perl在CGI刚出现时就已经存在)并因其是一种非常好的语言而闻名,因为它是一种通过CGI服务动态网页的语言。如今,还有其他替代方法可以在Web服务器上运行Perl,主要是mod_perl

C语言中的CGI编程使我很困惑。在C ?? 认真吗?我不知道该说些什么。我只是感到困惑。“在C中” ??这会改变一切。程序需要编译和执行。这完全改变了我对Web编程的看法。我何时编译?程序如何执行(因为它将是一个机器代码,因此它必须作为独立的进程执行。)它如何与Web服务器通信,IPC和如何使用套接字编程与所有服务器(在我的示例MATLAB和MySQL中)进行接口连接,我迷路了!

编译可执行文件一次,Web服务器将执行该程序,并将请求中的数据传递给该程序,然后输出接收到的响应。CGI指定每个请求将启动一个程序实例。这就是为什么CGI如今效率低下和过时的原因。

他们说CGI已过时。它不再使用。是这样吗?最新更新是什么?

当性能不是最重要的并且需要一种简单的执行代码的方法时,仍会使用CGI。由于前面提到的原因,它效率低下,并且在网络环境中有更现代的方法可以执行任何程序。当前最著名的是FastCGI


24
更具体地说,它描述了如何在环境变量(例如请求类型,远程IP地址)中传递请求信息,如何通过标准输入传递请求主体以及如何通过标准输出传递响应。有关详细信息,请参考CGI规范(hoohoo.ncsa.illinois.edu/cgi)。
daf

3
假设Server side Program您的图中是我的PHP脚本。所以,我从来没有做过CGI编程吗?因为我从未写过Web服务器和PHP脚本之间的任何内容。该死的!!这杀死了我。

4
PHP仍然很大程度上基于CGI协议,$ _ SERVER的大部分内容直接来自CGI规范。“ CGI编程”始终确实意味着程序在处理请求,而不是协议本身的实现。如果您向1993年的Web编程先驱者解释了使用PHP的方法,那么他会认为它是CGI编程的一种高级形式(尽管可能有些w弱)。
Michael Borgwardt 2010年

5
@Michael:但是通过mod_php运行时根本不是CGI(即使基于它)。我同意CGI既指协议又指通过它执行的脚本。
Vinko Vrsalovic

2
@Vinko Vrsalovic:如果CGI是Perl,C或其他语言在Web服务器中执行的接口,则PHP使用哪个接口在Apache中运行?PHP是否属于CGI规范?
hardik

63

CGI到底是什么?

Web服务器从程序(而不是文件)获取其数据的一种手段。

/cgi-bin/*.cgi有什么大不了的?

没什么大不了的。这只是一个约定。

我不知道服务器上的cgi-bin目录是做什么的。我不知道为什么他们有* .cgi扩展名。

服务器必须知道如何处理文件(即,将其视为要执行的程序,而不是简单地处理文件)。具有.html扩展名告诉它使用text / html内容类型。具有.cgi扩展名告诉它以程序运行。

将可执行文件保存在单独的目录中可提供一些额外的保护,以防止执行错误的文件和/或将CGI程序作为原始数据提供服务,以防服务器配置错误。

为什么Perl总是妨碍您。

没有。Perl和CGI一样大,而且很受欢迎。

我已经好多年没有使用Perl CGI了。我使用mod_perl已有很长时间了,这些天我倾向于使用FastCGI使用PSGI / Plack。

本书是使用Perl进行CGI编程的另一个很好的例子,为什么不使用“使用PHP / JSP / ASP进行CGI编程”。

CGI不是很有效。与Web服务器上的程序进行通讯的更好方法是在大约同一时间出现的。JSP和ASP 与程序对话的不同方法。

C语言中的CGI编程使我很困惑。在C ?? 认真吗?

这是一种编程语言,为什么不呢?

我什么时候编译?

  1. 写代码
  2. 编译
  3. 访问网址
  4. Web服务器运行程序

程序如何执行(由于它将是机器代码,因此必须作为独立的进程执行)。

它不必作为独立的进程执行(您可以用C编写Apache模块),但是CGI的整个概念是它启动了一个外部进程。

它如何与Web服务器通信?IPC?

STDIN / STDOUT和环境变量-在CGI规范中定义。

并使用套接字编程与所有服务器(在我的示例MATLAB&MySQL中)接口?

使用您喜欢和支持的任何方法。

他们说CGI已贬值。它不再使用。是这样吗?

CGI效率低下,缓慢且简单。它很少使用,使用时是因为它很简单。如果性能没什么大不了的话,那么简单就值得很多。

最新更新是什么?

1.1


1.编写代码2.编译3.访问URL 4. Web服务器运行程序。|| 但是,网络服务器如何知道您将已编译的可执行程序放在何处?它如何知道运行哪个可执行程序(在所有这些程序中)?
起搏器

@Pacerier —以相同的方式知道是否在请求静态文件的情况下将静态文件发送给客户端。
昆汀

41

CGI是Web服务器(HTTP服务器)和处理特定请求的某种类型的可执行程序之间的接口规范。

它描述了应如何将该请求的某些属性传达给该程序的环境,以及该程序应如何将响应传达回服务器,以及服务器应如何“完成”响应以形成对原始HTTP请求的有效回复。

有一段时间,CGI是IETF Internet草案,因此有一个有效期。它已过期且没有更新,因此没有CGI“标准”。现在它是一个参考性的RFC,但是正因为如此,它记录了通用做法,而不是标准本身。rfc3875.txtrfc3875.html

可以在目标计算机上以可运行的任何语言编写实现CGI接口的程序。它们必须能够访问环境变量,通常还可以访问标准输入,并且它们必须在标准输出上生成其输出

诸如C之类的编译语言与诸如perl之类的脚本语言一样,通常被使用,通常使用库来简化对CGI环境的访问。

CGI的主要缺点之一是为每个请求生成一个新程序,因此在请求之间保持状态可能是一个主要的性能问题。该状态可以用Cookie进行处理或以URL编码,但是如果状态变大,则必须将其存储在其他位置,并从编码的URL信息或cookie中键入密钥。然后,每个CGI调用都必须从某处的商店重新加载存储的状态。

因此,对于请求和会话的界面非常简单,Web服务器和应用程序之间更好的集成环境变得更加流行。诸如使用apache的现代php实现之类的环境将目标语言与Web服务器更好地集成在一起,并提供对有效处理http请求所需的请求和会话对象的访问。它们提供了一种更轻松,更丰富的方式来编写“程序”以处理HTTP请求。

是否编写CGI脚本取决于解释。当然可以做到这一点,但是将php作为模块运行的情况要普遍得多,其中脚本和服务器之间的接口严格来说并不是CGI接口。


1
烦。当没有其他答案时,我开始写这篇文章,但是被打了个电话。现在,它在列表中排名第8。我没有立即删除它的意愿,我会稍后再删除它。
CB Bailey 2010年

6
嘿..请不要删除它。它说得更清楚一些。我发现它很有帮助。也许其他一些人也会这样。:)

1
好吧,我待会儿再说。但是,如果有人将“更好”的段落整合到更完整的答案之一中,那可能会很好。然后,我们可能会得到更明确的答案。
CB Bailey 2010年

18

CGI在RFC 3875中指定,尽管这是原始NCSA文档的后来“正式”编纂。基本上,CGI定义了一种协议,用于将有关HTTP请求的数据从Web服务器传递到要处理的程序-任何程序,采用任何语言。在编写规范时(1993年),大多数Web服务器仅包含静态页面,“ Web应用程序”是一种罕见的新事物,因此将它们与“常规”静态内容区分开来似乎很自然,例如cgi-bin静态内容以外的目录,并以结束.cgi

目前,这里还没有像PHP这样的专用“ Web编程语言”,而C是主要的可移植编程语​​言-许多人使用C编写了CGI脚本。但是Perl很快证明更适合这种类型的CGI在一段时间内几乎与Perl成为同义词。然后出现了Java Servlet,PHP和许多其他应用程序,并占领了Perl的大部分市场份额。


为什么PHP是“专用的Web编程语言”?PHP是一种通用语言,人们也一直在将其用于UI应用程序。
起搏器

@Pacerier:它被设计为一种用于生成网页的编程语言,这就是其99.9%的用户使用它的目的。甚至以它的名字命名。声称其他任何东西都是毫无意义的。如果您正在将它用于UI应用程序,科学计算或嵌入式编程,那很好,请开心,没有人说您不允许这样做。
Michael Borgwardt 2015年

13

看看Wikipedia 中的CGI。CGI是Web服务器与外部程序或脚本之间的协议,该协议可处理输入并生成发送到浏览器的输出。

CGI是Web服务器和程序进行通信的简单方式,仅此而已。在这里,服务器管理网络连接和HTTP协议,程序处理输入并生成发送到浏览器的输出。CGI脚本基本上可以是任何可以由Web服务器执行并遵循CGI协议的程序。这样就可以在C语言中实现CGI程序。但是,由于C不太适合该任务,因此这非常少见。

/cgi-bin/*.cgi这是人们通常放置其CGI脚本的简单路径。默认情况下,通常将Web服务器配置为从该路径获取CGI脚本。

CGI脚本也可以在PHP中实现,但是所有PHP程序都不是CGI脚本。如果Web服务器已嵌入PHP解释器(例如Apache中的mod_php),则Web服务器和解释器之间的更有效的直接协议将跳过CGI阶段。

是否实现了CGI脚本取决于Web服务器如何执行脚本。


12

CGI本质上将请求传递给使用Web服务器配置的任何解释器-可能是Perl,Python,PHP,Ruby,C几乎任何东西。Perl是当今最常见的,这就是为什么您经常在参考CGI时看到它。

CGI还没有死。实际上,大多数大型托管公司都将PHP作为CGI而不是mod_php来运行,因为它提供了用户级别的配置和其他一些功能,而它却比mod_php慢。Ruby和Python通常也作为CGI运行。它们的主要区别在于服务器模块是作为实际服务器软件的一部分运行的-与CGI一样,它完全在服务器外部。服务器仅使用CGI模块来确定如何将数据传递和接收到外部解释器。


2
不降低投票率,但大多数python网络安装我都看到过mod_wsgi或mod_python上的位置。
ChristopheD

这就是大多数人使用术语CGI脚本的方式,但这与术语的含义并不完全相同。
reinierpost

您说的是解释器,但很少解释C,并且可以将C编译程序之类的编译程序用于CGI。
user34660

11

CGI是一种机制,通过该机制Web服务器可以调用外部程序来处理请求,并使用环境变量和标准输入将请求数据提供给程序。尽管使用某些语言编写CGI程序相对于使用其他语言编写CGI程序更容易,但是编写外部程序所使用的确切语言并不重要。

由于CGI脚本需要执行权限,因此默认情况下,httpd仅允许cgi-bin出于安全目的(可能现在被误导)运行目录中的CGI程序。

大多数PHP脚本通过来在Web服务器进程中运行mod_php。这不是CGI。

由于必须根据请求启动程序(和相关的解释器),因此CGI速度很慢。现代替代方案是mod_php使用的嵌入式执行和FastCGI使用的长时间运行的进程。一种给定的语言可能有自己的实现这些机制的方式,因此请务必在使用CGI之前先询问一下。


@Ignacio Vazquez-Abrams:如果CGI接口创建了一个新的进程,则每次收到CGI资源的请求时,CGI和mod_php之间的执行区别是什么?CGI和mod_php是相同的吗?还是可以编写在CGI接口而不是mod_php下运行的PHP脚本???
hardik

@Hardik:mod_php作为HTTPd的一部分运行,它负责其自身的进程。
伊格纳西奥·巴斯克斯

这个“外部程序”是什么?如果我使用php-fpm运行php,它是解释器吗?
slier 2015年

@slier:这是不是Web服务器的任意程序。
伊格纳西奥·巴斯克斯

@ IgnacioVazquez-Abrams所以可以安全地假设它是interpreter如果我用php-fpm运行php吗?
slier 2015年

7

您可能想知道什么不是CGI,答案是Web服务器的模块(如果我想您是Apache的话)。这就是很大的区别,因为CGI需要外部程序,线程,而无论要实例化PERL,PHP,C应用程序服务器,而当您以模块身份运行时,该程序本身就是Web服务器(apache)。

由于所有这些,因此会涉及许多性能,安全性和可移植性问题。但是首先了解不是CGI的东西是很不错的。


7

一个真实的例子:一个复杂的数据库需要在网站上显示。由于数据库是在1986年左右设计的(!),因此许多数据以不同的方式打包以节省磁盘空间。

随着开发的进行,开发人员无法再单独使用SQL解决复杂的数据请求,例如,因为排序算法不寻常。

有三种明智的解决方案:

  1. 快速又肮脏:将未存储的数据发送到PHP,在此处进行排序。显然,这是一个非常昂贵的解决方案,因为每次调用该页面时都会重复执行此操作
  2. 向数据库引擎编写插件-但管理员尚未准备好允许外部代码在其服务器上运行,或者
  3. 您可以在程序(C,Perl等)中处理数据,并输出HTML。该程序本身进入/ cgi-bin,并由Web服务器(例如Apache)直接调用,而不是通过PHP调用。

CGI在解决方案3中运行您的脚本,并将效果输出到浏览器。您具有已编译程序的速度,比SQL强的语言灵活性,并且无需将插件编写到SQL Server。(同样,这是特定于SQL和C的示例)


1
对我来说最好的答案,我明白了。
Daniel Katz

7

CGI脚本是控制台/外壳程序。在Windows中,当您使用“命令提示符”窗口时,将执行控制台程序。当Web服务器执行CGI脚本时,它将使用环境变量或“标准输入”向控制台/ shell程序提供输入。标准输入就像在控制台/ shell程序中输入数据一样。对于CGI脚本,Web服务器进行键入。CGI脚本将数据写出到“标准输出”,并将该输出作为HTML页面发送到客户端(Web浏览器)。标准输出类似于您在控制台/ shell程序中看到的输出,除了Web服务器读取它并将其发送出去。

可以从浏览器执行CGI脚本。URI通常包括提供给CGI脚本的查询字符串。如果方法是“ get”,那么查询字符串将在名为QUERY_STRING的环境变量中提供给CGI脚本。如果方法是“ post”,则使用标准输入将查询字符串提供给CGI脚本(CGI脚本从标准输入中读取查询字符串)。

CGI脚本的早期使用是处理表单。在HTML的开头,HTML表单通常具有“操作”属性和一个指定为“提交”按钮的按钮。当按下提交按钮时,“操作”属性中指定的URI将与来自表单的数据作为查询字符串一起发送到服务器。如果“操作”指定了CGI脚本,则将执行CGI脚本,然后生成HTML页面。

RFC 3875“通用网关接口(CGI)”部分使用C定义了CGI,就像说环境变量“由C库例程getenv()或变量environ访问”一样。

如果您正在使用C / C ++开发CGI脚本并使用Microsoft Visual Studio来执行此操作,那么您将开发一个控制台程序。


“ CGI脚本”是一个广义术语,也可以包含可执行文件。
71GA

6

CGI是您编写的程序(或Web API),并将其保存在Web Server站点上。CGI是一个文件。

该文件坐在Web服务器上等待。当客户端浏览器向Web服务器发送执行CGI文件的请求时,Web服务器将在服务器站点上运行CGI文件。此CGI程序的输入(如果有)来自客户端浏览器。该CGI程序的输出发送到浏览器。

您使用哪种语言编写CGI程序?其他帖子已经提到c,java,php,perl等。


4

CGI背后的思想是程序/脚本(无论是Perl还是C)都通过STDIN(请求数据)接收输入,并通过STDOUT(echo,printf语句)输出数据。

大多数PHP脚本不合格的原因是它们在PHP Apache模块下运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.