Sign in Join
Wiki copytemporary

Revision 2 of 2, by WikiArchive on 11-10-2026. The page as it is now.

CGI Web Programming/zh CN

本文涉及简单的 CGI 程序。请注意,选用一种 Web 框架开发效率可能会更高。

关于 CGI

CGI (公共网关接口)的工作原理很简单:

假设有两台计算机:

只有主机上的 Web 服务程序支持 CGI 功能,您才能使用 CGI。把所有文件放入主机后,CGI 程序通常可以如下启动: **http://www.yourserver.com[.xx]/yourlogin/cgi-bin/cginame.exe**

注意:

Free Pascal CGI 程序及测试方式

和其他程序一样,用 Free Pascal 编写的 CGI 程序就是普通的可执行程序。与 Perl 或 Python 编写的 CGI 程序不同,用 Free Pascal 编写的 CGI 程序不是解释执行的,而是独立运行的可执行程序。

若要测试 CGI 程序,电脑中必须装有支持 CGI 功能的 HTTP 服务 程序。 推荐一款优秀的 HTTP服务器:Apache,Windows 和 Linux 均可支持。

十分简单的示例

以下是一个迷你 CGI 程序的示例,仅供演示。

  1. 设置 Cookie
  2. 输出 Content-Type(即声明可输出合法的 HTTP 文本)
  3. 读取 Cookie
  4. 以 GET 方式读取表单数据
  5. 以 POST 方式读取表单数据
pascal
program mini;
    
    uses dos;
    
    var
      a:string;
      c:char;
    begin
      //set a cookie (must come before content-type line below)
      //don't forget to change the expires date
    writeln('Set-cookie:widget=value; path=/; expires= Mon, 21-Mar-2005  18:37:00 GMT');
    
      //output legal http page
      writeln('Content-Type:text/html',#10#13);
    
      //demonstrate get cookies
      a:= GetEnv('HTTP_COOKIE');
      writeln('cookies:',a);
      
      //demonstrate GET result
      a:='';
      a:= GetEnv('QUERY_STRING');
      writeln('GET: ',a);
        
      //demonstrate POST result 
      a:='';
      while not eof(input) do
      begin
         read(c);
         a:= a+c;
      end;	 
      writeln('POST: ',a);
    end.

简单的点击计数程序

hitcounter 程序可为网站提供简单的点击计数功能。可以考虑在配置文件中加入阻止列表,以便不把机器人程序和自己的计算机纳入统计。当然还可以有更多改进,比如设置 Cookie 让每个会话只能获得一次点击计数,但这已足以介绍 CGI 编程了。

代码在此:1(http://sourceforge.net/p/modelbuilder/code/HEAD/tree/html/cgi/)

Debugging CGI

因为 CGI 程序不会往屏幕上显式信息,而且是由其他进程(Web 服务程序)启动的,调试起来要比桌面应用困难得多。

有一种解决方案是让 CGI 应用程序启动一个调试器: 程序引用单元代码时,作为初始化过程之一,将新开一个进程,该进程会打开终端(windows中的cmd、linux中的xterm)并启动附着于调用过程的 gdb 调试器。

这里主程序会暂时“Sleep”一会儿,以确保 gdb 能完成初始化。

这种方案已在以下平台通过测试:

更多说明详见单元代码。

pascal
unit SelfDebug;
    
    {
    Instructions:
    -Include unit anywhere in the program.
    -Change DEBUGGER constant to match your debugger (gdb, ddd,gdbtui...)
    -For Windows, if the program to debug is running as a service (e.g. CGI application
     from Apache running as a service), make sure the service is configured with
     "Interact with desktop" checked. Failing to do so, the debugger will be started
     without a console, break the program and hang waiting for input. Killing the debugger
     is your only option.
    -For Linux, if the program to debug is running as a different user (e.g. CGI application),
     run "xhost +" in a terminal to enable all users to connect to xserver.
     If needed, change DISPLAY to match your DISPLAY environment variable
    }
    
    {$mode objfpc}{$H+}
    
    interface
    
    uses
      Classes, SysUtils,Process;
    
    implementation
    
    const
      {$ifdef windows}
      DEBUGGER='C:\lazarus\mingw\bin\7.3\gdb.exe';
      {$endif}
      {$ifdef linux}
      DEBUGGER='gdb';
      DISPLAY=':0.0';
      {$endif}
      MSWAIT=2000;
    
    var
      AProcess: TProcess;
    
    initialization
    AProcess := TProcess.Create(nil);
    {$ifdef windows}
    AProcess.CommandLine := format('cmd /C START "Debugging %s" /WAIT "%s" "%s" %d"',[paramstr(0),debugger,paramstr(0),GetProcessID]);
    {$endif}
    {$ifdef linux}
    AProcess.CommandLine := format('xterm -display %s -T "Debugging %s" -e "%s" "%s" %d',[DISPLAY,paramstr(0),DEBUGGER,paramstr(0),GetProcessID]);
    {$endif}
    AProcess.Execute;
    sleep(MSWAIT);
    finalization
    AProcess.Free;
    end.

源代码:http://www.hu.freepascal.org/lists/fpc-pascal/2011-October/030752.html

有关调试的其他解决方案,是将调试信息写入文件或事件日志 log/syslog。

Existing CGI Frameworks

现成的 CGI 单元代码和框架已有很多了,而且能设置 Cookie、会话、读取 POST 和 GET 信息,因此直接使用 CGI 显得微末了。


From the Free Pascal wiki, page "CGI Web Programming/zh CN", as the Internet Archive kept it on 2025-02-11, last changed on 2024-09-22. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.