| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 440 人关注过本帖
标题:foxpro web 开发原理(四)
只看楼主 加入收藏
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:915
专家分:1401
注 册:2021-10-13
结帖率:97.44%
收藏
已结贴  问题点数:20 回复次数:4 
foxpro web 开发原理(四)
今天的文章是我们的最重要的一篇文章,读完这篇文章,我们就完全了解CGI的来龙去脉,你完全可以根据这个原理,运用自己擅长的编程语言,开发出自己的Web开发工具,一个贴合自己的应用程序的web开发应用,随时可以根据自己的需求更改的web开发应用。相信有些已经拥有foxweb,vfpweb等web应用程序的朋友会嗤之以鼻,人家早就有了,拿来用就行了。。。

呃,我想说是的,的确早就有现成的,拿来就可以用的。如果你想熟练运用,可能需要全网搜索说明档,范例,源代码等,否则就算拿到软件,也不知道怎么运用,最后可能还是要花钱去买。而你当初想用这些软件的时候就是不想破费。。。

当然,我向来是支持知识付费的,因为很有可能我们也希望能运用自己的知识技能来获得财富。至少我们付费购买这些知识可以节省时间成本,快速地让自己的应用落地,从而赚钱,事实上,很多大神就是这么做的。像我这样的野生程序员,其实是很羡慕的,无法运用自己的知识快速变现,只能苦逼地为了生活奔波,偶尔抽点时间在论坛里发表几篇文章,证明自己还是有点技术的,只是生不逢时,选错了职业而已。。。

言归正传,今天我们要做到的是,如何让我们CGI去执行我们编写的脚本,再把执行后的结果返回给IIS服务器(也可以是其他服务器,原理都一样。)记得,当初有人在论坛里提问,如何在运行时执行grid里某个特定单元格,或行,或列的代码时,很困惑,因为设计时并没有写入代码,而是运行时,希望它能运行我们的某段代码,论坛里的解决方案是,用bindevent函数,这是个强大的函数,可以在运行时刻,让原本没有编写代码的事件运行某段代码。而看完这篇文章,或许你有不一样的解决方案。

依然以control为例,我们在编译它的时候,并不知道它要运行什么样的脚本,而脚本是文本的,也就是说,要实时编译它,并运行。所幸foxpro有这个功能函数,compile!

先来设计我们的脚本sample.fpx,我们探讨的是原理,所以尽量简单,让大伙明白。
只用了一句,代码如下:
response.write("It is success when you see this message!")

如果能正确运行,就显示这句英文“当你看到这条消息时,那就是成功了!”这里的response是我们在control中申明的一个public的对象,只有这样,我们的脚本和我们的CGI程序才有内在的联系,实时上,成熟的web应用都有这样的对象,如request,server,cookie,session等,用以保存服务器一些特定的信息,以及执行某些特定的功能。

昨晚在foxpro web 开发原理(三)中对control做了一点更改,或者说升级,为今天的修改埋下伏笔。感兴趣的可以参考:https://bbs.bc-cn.net/thread-514324-2-1.html

今天我们对CASE cmethod="GET" 的分支做进一步改进,让它开始执行脚本!

改进后的control代码如下:
程序代码:

* 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"
cmethod=GETENV("REQUEST_METHOD")

* 主程序
CLEAR
SET TALK OFF
SET CONSOLE OFF

* 获取标准输入输出句柄
hStdIn = GetStdHandle(STD_INPUT_HANDLE)
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)

* 调试用暂停(如果需要)
* [color=#808080]=Sleep(6000)  && 暂停60秒等待调试器附加[/color]
lcResponse=""

PUBLIC response &&创建public对象response,实例化myresponse
response=CREATEOBJECT("myresponse", hStdOut)

DO CASE 
    CASE cmethod="POST"
        * 读取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
        * 构建响应        
        lcResponse = "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ;
                "Content-Type: text/html" + CHR(13) + CHR(10) + ;
                CHR(13) + CHR(10) + ;
                "Hello " + lcValue
    
    CASE cmethod="GET"
        SET PATH TO 
        cpath=GETENV("PATH_TRANSLATED")
        cquerystr=GETENV("QUERY_STRING")
        IF FILE(cpath)  && 直接检查脚本文件是否存在
            * 构建响应头
            lcResponse1 = "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ;
                    "Content-Type: text/html" + CHR(13) + CHR(10) + ;
                    CHR(13) + CHR(10)
            response.write(lcResponse1)
            response.write("请求路径为: " + cpath+"<br>"+;
                    "请求参数为:" +IIF(EMPTY(cquerystr),"没有参数!",cquerystr))
            response.write("<br>")
            * 编译后直接执行.fpx文件
            COMPILE (STRTRAN(cpath,"fpx","prg"))
            DO (JUSTFNAME(cpath))
            RETURN
         ELSE 
             lcResponse = "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ;
                "Content-Type: text/html" + CHR(13) + CHR(10) + ;
                CHR(13) + CHR(10) + ;
                "错误:请求的脚本"+cpath+"不存在或已删除!"
         ENDIF                  

    OTHERWISE 
        lcResponse = "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ;
                "Content-Type: text/html" + CHR(13) + CHR(10) + ;
                CHR(13) + CHR(10) + ;
                "错误:目前只支持GET和POST方法!"
ENDCASE                     

* 发送响应
IF !EMPTY(lcResponse)
    lnBytesWritten = 0
    =WriteFile(hStdOut, lcResponse, LEN(lcResponse), @lnBytesWritten, 0)
ENDIF 

* 清理
CLEAR DLLS
RETURN  

* 构建myresponse类
DEFINE CLASS myresponse as Custom
hStdOut = 0

PROCEDURE Init
LPARAMETERS hOutput
    THIS.hStdOut = hOutput
ENDPROC

PROCEDURE write 
LPARAMETERS cstring
    lnBytesWritten = 0
    =WriteFile(THIS.hStdOut, cstring, LEN(cstring), @lnBytesWritten, 0)
ENDPROC 
ENDDEFINE


当运行不存在的脚本时,结果如下:
图片附件: 游客没有浏览图片的权限,请 登录注册


当运行存在的脚本时,结果如下:
图片附件: 游客没有浏览图片的权限,请 登录注册


到此,我们web开发的原理全部走通,接下来,就是完善它!!!
搜索更多相关主题的帖子: 运行 开发 脚本 web INTEGER 
6 天前 10:30
schtg
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:Usa
等 级:贵宾
威 望:67
帖 子:2046
专家分:4180
注 册:2012-2-29
收藏
得分:10 
回复 楼主 sam_jiang
6 天前 16:10
wcx_cc
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:52
帖 子:431
专家分:1371
注 册:2015-10-2
收藏
得分:10 
支持!赞赞赞!。但是需要从头学习。比如:在远程云平台上,自己安装了IIS,在云平台上的 D:\web文件夹里放入了一个HTML文档,这个文档里有调用 D:\exec\myexe.exe的功能,怎样才能实现:从本地电脑输入一个网址,通过IIS,就可以启动云平台上的HTML,从而能够启动vfp编译的执行文件,云平台要经过哪些设置,或要配备哪些文件,才能实现了这种功能,如果做到了,vfp编写的软件不就成为BS架构的了吗?我认为好像很难的事吧!所以还是得从头学。
5 天前 19:37
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:915
专家分:1401
注 册:2021-10-13
收藏
得分:0 
5 天前 23:01
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:915
专家分:1401
注 册:2021-10-13
收藏
得分:0 
5 天前 23:10
快速回复:foxpro web 开发原理(四)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020911 second(s), 9 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved