使用delphi 开发 web(二)动态脚本的实现

简介: 看了前面的文章同学,都会认为delphi 开发web比较麻烦,没有PHP 和ASP 方便。 因为每次要改动网页的内容,就要重新编译一次,重新发布一次,这样也太麻烦了。那么我们就 做一个类似PHP 的动态web 服务器吧,一次编译发布后,就不用再改了,网站内容需要变化时,只 需要修改脚本就可以了。

   看了前面的文章同学,都会认为delphi 开发web比较麻烦,没有PHP 和ASP 方便。

因为每次要改动网页的内容,就要重新编译一次,重新发布一次,这样也太麻烦了。那么我们就

做一个类似PHP 的动态web 服务器吧,一次编译发布后,就不用再改了,网站内容需要变化时,只

需要修改脚本就可以了。

先看看下面的代码:

<%

var

   i:integer;

begin

for i:=1 to 10 do

  print('ok');

%>

 <p> 你好<p>

<%

 end.

%>

非常像PHP 吧,不过语法是Pascal.我们把这个代码保存成test.psp(psp=pascal script page).

那么由于要解释pascal 脚本,我们需要一个pascal 脚本解释器,目前支持delphi 的pascal 脚本解释器

主要有fastscript,pascalscript,tms script 和paxcompiler.我选择使用速度最快的、稳定性最好的paxcompiler.

当然需要把paxcompiler 封装一下,使其可以读入psp 文件并进行解释输出HTML.

unit paxWebScriptPP;

interface


uses
  SysUtils, Classes, HTTPProd , paxWebScripter,PaxCompiler, PaxProgram;

type
  TpaxPageProducer = class(TCustomPageProducer)
  private
    FcompileFile:Tfilename;
    FWebScripter: TpaxWebScripter;
    function GetOnPrint:  TPaxPrintEvent;
    procedure SetOnPrint(const Value:  TPaxPrintEvent );
     function GetOnInclude: TPaxCompilerIncludeEvent;
    procedure SetOnInclude(Value: TPaxCompilerIncludeEvent);

    procedure SetCompileFile(const Value: TFileName);


  protected

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    function ContentFromStream(Stream: TStream): string; override;

    property WebScripter: TpaxWebScripter read FWebScripter;

    function ContentFromCompileFile:string;
    function CompileToFile(Aoutfilename:Tfilename):string;

  published
    property HTMLDoc;
    property HTMLFile;

    Property CompileFileName:Tfilename read FcompileFile write SetCompileFile;


    property OnPrint: TPaxPrintEvent read GetOnPrint write SetOnPrint;

    property OnInclude: TPaxCompilerIncludeEvent read GetOnInclude write SetOnInclude;

  end;

然后在webbroke 里面根据浏览器发送的请求处理,完成脚本的运行。当然了在系统初始化时先要注册一些

常用的函数和类。

    initialization

    g_UnitList := TUnitList.Create;
    g_UnitList.AddClass(Twm);
    g_UnitList.Sort;
    RegisterUnits(g_UnitList, GlobalImportTable);
  // 以上代码使用于delphi 2010 以后,直接利用delphi 本身的RTTI 功能,注册需要使用的类


  RegisterHeader(0,'function Utf8ToAnsi(const S: String): string;',@utf8toansi);
  RegisterHeader(0,'function myExtractStrings(Separators: Char; Content: string;var Strings: TStrings): Integer;',@myExtractStrings);
  RegisterHeader(0,'function getmin(date1,date2:string):integer;', @getmin);
  RegisterHeader(0,'function getstringbylen(src:string;len:integer):string;',@getstringbylen);
  RegisterHeader(0,'function MD5(const s: string): string;', @MD5);
  RegisterHeader(0, 'function IPValid(ip1,ip2,myip:string):boolean;', @IPValid);
  RegisterHeader(0, 'function Now: TDateTime;', @now);

// 注册自己的过程

 

加入现在URL的为 http://www.51delphi.com/web?path=test

 

处理URL

 procedure Twm.wmWebActionItem1Action(Sender: TObject; Request: TWebRequest;
  Response: TWebResponse; var Handled: Boolean);
var
  path, s, LFilename : string;
  fn: string;
  fnindex: string;
  ts: tstringlist;
  showtime: Boolean;
  istart, iend: LongWord;
  i:integer;
begin
 {$IFDEF INDYSERVER}
    pathname := pathnamefix + pathdelim +
      copy(UnixPathToDosPath(mypath), 2, 100);

{$ELSE}
    pathname := pathnamefix + pathdelim + copy(mypath, 2, 100);
{$ENDIF}

   fnindex := pathname + pathdelim + 'index.html';
   cookpath := webpath + mypath; // web 为路径
   path := Request.QueryFields.Values['path'];

  if path = '' then
    begin
      path := 'index';
      if FileExists(fnindex) then // 有index.html
      begin
         response.ContentStream:=TFileStream.Create(fnindex, fmOpenRead + fmShareDenyWrite);
         Exit;
      end;

    end;

      if path = 'genindex' then // 生成index 页
    begin
      procindex;
      Response.Content := '首页生成成功!';
      Exit;
    end;

    if path = 'prochtml' then // 生成静态页面
    begin
      if Request.QueryFields.Values['file'] = '' then
      begin
        Response.Content := '请输入文件名!';
        Exit;
      end;
      path := Request.QueryFields.Values['file'];
      fn := pathname + pathdelim + path + '.psp';
      if not FileExists(fn) then
      begin
        Response.Content := '文件名不存在!';
        Exit;
      end;
      fn := path;
      prochtml(fn);
      Response.Content := '页面生成成功!';
      Exit;
    end;


   qlist := TClasslist.Create; // 这个是用来在脚本里面实现动态生成Query.
   try

      show.WebScripter.Scripter.Reset;
      show.WebScripter.Scripter.RegisterVariable(0,'request:TWebRequest;',@Request);
      show.WebScripter.Scripter.RegisterVariable(0,'response:TWebResponse;',@Response); //注册request 和response,以便在脚本里面运行。
      show.WebScripter.Scripter.RegisterVariable(0,'wm:Twm;', @self);
      

    fn := pathname + pathdelim + path + '.html';
    if FileExists(fn) then
    begin
       response.ContentStream:=TFileStream.Create(fn, fmOpenRead + fmShareDenyWrite);
      Exit;
    end;

    fn := pathname + pathdelim + path + '.psp';

    if Request.QueryFields.Values['debug'] = 'true' then
      debug := True;
     showtime := False;
    if Request.QueryFields.Values['showtime'] = 'true' then
      showtime := True;



    if not FileExists(fn) then
    begin
      if debug then
      begin
        Response.Content := '找不到你要的文件:' + fn;
        Exit;
      end
      else
      begin
        Response.Content := '找不到你要的文件';
        Exit;
      end;
    end;
    show.HTMLFile := fn;
    if not showtime then
     begin
        Response.Content := show.Content;
    end
    else
    begin
      istart := GetTick;
      s := show.Content;
      iend := GetTick;
      Response.Content := s + '<p>' + IntToStr(iend - istart) + '毫秒<p>';

    end;
  
  finally
    for i := 0 to qlist.Count - 1 do
    begin
      if Twebquery(qlist[i]) <> nil then
        Twebquery(qlist[i]).Free;
    end;
    qlist.Free;
  end;

end;

OK,  大功告成。

以上就实现了脚本的运行,并可以处理request 和response 对象。

 

运行结果如下:

如果大家想体验一下更多的功能和效果,可以访问一下网站

www.xasyu.cn

 

 

 

目录
相关文章
|
20天前
|
监控 JavaScript 前端开发
《理解 WebSocket:Java Web 开发的实时通信技术》
【4月更文挑战第4天】WebSocket是Java Web实时通信的关键技术,提供双向持久连接,实现低延迟、高效率的实时交互。适用于聊天应用、在线游戏、数据监控和即时通知。开发涉及服务器端实现、客户端连接及数据协议定义,注意安全、错误处理、性能和兼容性。随着实时应用需求增加,WebSocket在Java Web开发中的地位将更加重要。
|
1月前
|
Web App开发 前端开发 开发工具
介绍Web开发的基础知识
介绍Web开发的基础知识
29 7
|
6天前
|
JSON Java fastjson
Spring Boot 底层级探索系列 04 - Web 开发(2)
Spring Boot 底层级探索系列 04 - Web 开发(2)
15 0
|
6天前
|
安全 编译器 PHP
PHP 8.1版本发布:引领Web开发新潮流
PHP编程语言一直是Web开发的主力军,而最新发布的PHP 8.1版本则为开发者们带来了更多创新和便利。本文将介绍PHP 8.1版本的主要特性,包括更快的性能、新的语言功能和增强的安全性,以及如何利用这些功能来提升Web应用程序的质量和效率。
|
9天前
|
PHP
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
|
9天前
|
前端开发 数据挖掘 API
使用Python中的Flask框架进行Web应用开发
【4月更文挑战第15天】在Python的Web开发领域,Flask是一个备受欢迎的轻量级Web框架。它简洁、灵活且易于扩展,使得开发者能够快速地构建出高质量的Web应用。本文将深入探讨Flask框架的核心特性、使用方法以及在实际开发中的应用。
|
18天前
|
安全 前端开发 Java
Java Web开发知识点学习总结
Java Web开发涉及Java基础、Servlet、JSP、数据库操作(SQL+JDBC)、MVC设计模式、Spring框架、Hibernate ORM、Web服务(SOAP&RESTful)、安全认证(HTTP Basic/Digest/OAuth)及性能优化(缓存、异步、负载均衡)。
17 3
|
21天前
|
XML JSON JavaScript
使用JSON和XML:数据交换格式在Java Web开发中的应用
【4月更文挑战第3天】本文比较了JSON和XML在Java Web开发中的应用。JSON是一种轻量级、易读的数据交换格式,适合快速解析和节省空间,常用于API和Web服务。XML则提供更强的灵活性和数据描述能力,适合复杂数据结构。Java有Jackson和Gson等库处理JSON,JAXB和DOM/SAX处理XML。选择格式需根据应用场景和需求。
|
25天前
|
前端开发 JavaScript 数据管理
描述一个使用Python开发Web应用程序的实际项目经验,包括所使用的框架和技术栈。
使用Flask开发Web应用,结合SQLite、Flask-SQLAlchemy进行数据管理,HTML/CSS/JS(Bootstrap和jQuery)构建前端。通过Flask路由处理用户请求,模块化代码提高可维护性。unittest进行测试,开发阶段用内置服务器,生产环境可选WSGI服务器或容器化部署。实现了用户注册登录和数据管理功能,展示Python Web开发的灵活性和效率。
14 4
|
1月前
|
API
2024常用Web支付开发讲解教程
本教程为web支付开发,讲解了最常用的两钟支付:支付宝支付和微信支付,服务器配置和API对接,学完本课程可以学会微信支付、和支付宝支付开发。
18 2
2024常用Web支付开发讲解教程