foxpro web 开发原理(三)
上次我们实现了cgi转发功能,不论我们请求哪个fpx文件,cgi程序都会向iis发送一个问候:“hello”今天我们来探索IIS服务器是如何把请求的路径和参数发给我们cgi程序的。
当我们向浏览器发送请求:http://localhost/sample.fpx?name=samjiang时,我设想此时IIS收到请求,会把网址以参数的形式发回给我们的cgi程序,于是我为control.prg设置了2个参数,lcpath 和lcqureystring,编译试试~

parameters lcpath,lcqureystring if parameters()=0 lcoutput="没有参数被传递!" else 。。。 endif
很显然,这条路行不通,IIS并没有向我们的CGI程序control传递任何参数

那就说明IIS把我们的请求以环境变量的形式保存在服务器上了。
我虽不知道保存的环境变量名是什么,但这难不倒我,嘿嘿,写个foxweb脚本,看看当我们发出一个请求时,服务器会自动生成哪些环境变量。
foxweb代码:

<% *本脚本showvars.fwx用来显示所有环境变量 dime aServerVars[1] &&定义一个服务器变量数组 nTotVars = Request.ServerVariablesArray(@aServerVars) for i=1 to ntotvars response.write(aServerVars[i]) &&在浏览器中显示所有环境变量 response.write("<br>") endfor %>
浏览器显示如下:
发现2个有用的环境变量PATH_TRANSLATED和QUERY_STRING,我们的CGI程序要执行自定义脚本sample.fpx时,必须知道我们的脚本保存的物理路径,以及它的请求参数(当然可以没有参数)
在这篇文章里,我们依然没有对sample.fpx脚本进行解释执行,只是为了了解IIS如何将请求传递给我们的CGI程序control。
现在我们可以对control做出更改,编译后执行试试看~~~
control.prg代码如下:

* CGI处理示例 * 定义 Windows API 常量 #DEFINE STD_INPUT_HANDLE -10 #DEFINE STD_OUTPUT_HANDLE -11 * 声明 Windows API DECLARE Sleep IN kernel32 INTEGER dwMilliseconds DECLARE INTEGER GetStdHandle IN kernel32 INTEGER nStdHandle DECLARE INTEGER ReadFile IN kernel32 ; INTEGER hFile, ; STRING @lpBuffer, ; INTEGER nNumberOfBytesToRead, ; INTEGER @lpNumberOfBytesRead, ; INTEGER lpOverlapped DECLARE INTEGER WriteFile IN kernel32 ; INTEGER hFile, ; STRING lpBuffer, ; INTEGER nNumberOfBytesToWrite, ; INTEGER @lpNumberOfBytesWritten, ; INTEGER lpOverlapped * CGI 环境变量常量 CGI_CONTENT_LENGTH = "CONTENT_LENGTH" * 主程序 CLEAR SET TALK OFF SET CONSOLE OFF * 获取标准输入输出句柄 hStdIn = GetStdHandle(STD_INPUT_HANDLE) hStdOut = GetStdHandle(STD_OUTPUT_HANDLE) * 调试用暂停(如果需要) =Sleep(6000) && 暂停60秒等待调试器附加 * 读取POST内容 lcContentLength = GETENV(CGI_CONTENT_LENGTH) lnContentLength = VAL(lcContentLength) IF lnContentLength > 0 * 准备缓冲区 lcReadBuffer = REPLICATE(CHR(0), lnContentLength) lnBytesRead = 0 * 读取输入 =ReadFile(hStdIn, @lcReadBuffer, lnContentLength, @lnBytesRead, 0) lcReadBuffer = LEFT(lcReadBuffer, lnBytesRead) * 解析参数 lnPos = AT("=", lcReadBuffer) IF lnPos > 0 lcValue = SUBSTR(lcReadBuffer, lnPos + 1) ELSE lcValue = lcReadBuffer ENDIF ELSE lcValue = "" ENDIF cpath=GETENV("PATH_TRANSLATED") cqureystr=GETENV("QUERY_STRING") * 构建响应 lcResponse = "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ; "Content-Type: text/html" + CHR(13) + CHR(10) + ; CHR(13) + CHR(10) + ; "请求路径为: " + cpath+"<br>"+; "请求参数为:" +IIF(EMPTY(cqureystr),"没有参数!",cqureystr) * lcResponse [color=#808080]= "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ;[/color] "Content-Type: text/html" + CHR(13) + CHR(10) + ; CHR(13) + CHR(10) + ; "Hello " + lcValue * 发送响应 lnBytesWritten = 0 =WriteFile(hStdOut, lcResponse, LEN(lcResponse), @lnBytesWritten, 0) * 清理 CLEAR DLLS QUIT
在浏览器中运行效果如下:
1,没有参数的情况:
2,有参数的情况:
完美。。。
预告一下~~~ 下一篇,我们就可以执行我们自己的脚本了