实现一个cgi程序前必须知道为什么会产生cgi?cgi的作用是什么?以下解释简单粗暴,不当之处请谅解。
几乎所有的web服务器能直接把静态的文件进行解析并且返回给浏览器端,但是遇到动态文件,即php,asp,jsp等动态语言文件web服务器没办法解析代码并返回。于是web服务器开发商和众多的后端开发商约定如下内容:
(1).web服务器遇到动态脚本文件会将大部分的客户端请求信息转发给cgi的程序,让cgi自己处理好再返回给web服务器
(2).cgi程序只做两件事情,一是接收web服务器数据,二是输出数据到web服务器
(3).web服务器相互传递数据的方法为使用系统环境变量
说白了就是web服务器并不能直接运行php,asp,jsp这样的文件,于是和各大语言定的协议。
言归正传,开始写一个简单的cgi程序说明一下。cgi只是一种协议,用任何支持标准输出和输入的语言都支持编写cgi程序。这里演示使用c#。假设我现在使用的是iis服务器,需要支持一门叫JQ(嘉强)的后端脚本语言,我的cgi使用c#编写。
(1).code1:
static void Main(string[] args) { /** * 第一步:获取WEB服务器请求数据(具体自查cgi环境变量大全) * (1).请求的脚本文件.eg:D:\wwwroot\learn\index.jq * (2).用户数据.eg:get/post * (3).请求方式.eg:get/post */ string path = Environment.GetEnvironmentVariable("PATH_TRANSLATED"); string query = Environment.GetEnvironmentVariable("QUERY_STRING"); string method = Environment.GetEnvironmentVariable("REQUEST_METHOD"); /** * 第二步:通用Response Header输出(严格上应该支持脚本自定义的header.不能直接\n\n) */ Console.Write("Content-Type: text/html; charset=GBK;\n"); Console.Write("X-Powered-By: JQ/7.2.4;\n\n"); /** * 第三步:文件IO打开请求的脚本文件,解析并编译代码,输出内容给WEB服务器 */ analyze.execute(File.ReadAllText(@path)); }
(2).code2:
class analyze { public static void execute(string codes) { string pattern = @"\((.*)\)"; foreach (Match match in Regex.Matches(codes, pattern)) { string code = match.Value; code = code.Replace('(',' '); code = code.Replace(')',' '); code = code.Replace('\'',' '); Console.Write(code); } } }
(3).code3:jq编程语言的后端文件:
<?jq System.out('<!DOCTYPE html><html><head><meta charset="utf-8"><title>我是jq服务端(runoob.com)</title></head><body>'); System.out('<span style="color:red">jq是世界上最好的编程语言</span>'); System.out('</body></html>');
解析:上面的cgi程序会根据浏览器请求的文件去查找后端文件的实际路径,并获取文件的代码,编译为真正执行的机器码。(上面的只是例子,简单替换为c#),然后进行输出给web服务器。当然如果你有兴趣可以通过创建代码解析器编写cgi来创建一门新的web脚本语言。
(4).上面的代码编写完成后我们需要编译为exe或者dll扩展文件
(5).直接访问我的本地网站,输出了code3的代码内容,说明暂时不支持jq后缀的动态语言支持
(6).IIs中添加程序映射和cgi限制。设置默认文档为index.jq,再次访问解析成功
感兴趣可以使用c来编写cgi实现新的语言,但是建议还是选择fastcgi,cgi这种用完即走的形式并发扛不住。