WebBroker StandAlone 模式下当作一个普通的 WebServer 响应静态网页或其它文件的请求
2017-04-13 21:58
288 查看
用 WebBroker 开发网页服务器端程序,在第一个阶段,最好采用 StandAlone 模式。开发完成后,再重新编译成 CGI 或者 ISAPI 或者 APACHE 的模块用于实际环境。这样的好处是 StandAlone 模式下它就是个独立的程序,非常方便 Debug,可以很容易地在 Delphi IDE 里面单步跟踪调试。
在 StandAlone 模式下,WebBroker 的程序就是一个独立的 EXE,这个 EXE 自己内嵌了一个 HTTP Server,无需额外的 IIS 或者 APACHE 作为 HTTP Server。
在这种情况下,如果浏览器请求一个静态网页,比如 abc.html,WebBroker 程序该如何响应,才能像是 IIS 一样将这个静态网页文件发送给浏览器?如果是 CSS 文件,或者 JavaScript 文件,又该如何响应?
以下代码,我自己测试过,能够正常运行,完全可以把一个 WebBroker 框架的 Delphi 程序当作一个类似 IIS 的 HTTP SERVER 来用。
procedure TWebModule1.HandleFileRequest(const FileName: string; Request: TWebRequest;
Response: TWebResponse);
var
FC, Ext: string;
FS: TFileStream;
SL: TStringList;
begin
{------------------------------------------------------------------------------
处理来自浏览器对静态页面文件的请求:
对于 Stand alone 模式的 WebBroker 程序,这个默认 Action 可以用来当作一个 Web Server 的根:
如果请求的 path 是一个文件,则返回一个文件给客户端。这样,http://ip/WebBroker.exe/abc.html
就可以从这里返回。
------------------------------------------------------------------------------}
if FileExists(FileName) then
begin
//以下代码,测试通过。网页里面有图片链接。网页能够正确显示图片。
Ext := LowerCase(ExtractFileExt(FileName));
if (Ext = '.html') or (Ext = '.htm') or (Ext = '.css') or (Ext = '.js') or (ext = '.txt') then
begin
{-----------------------------------------------------------------------
下载文本文件给浏览器,不能将文本文件加载为字符串然后用字符串返回,
而是应该直接用 Stream 来返回。用字符串返回,可能会有问题。估计原因是文件里面的字符串有些字符的编码有问题导致。
----------------------------------------------------------------------}
FS := TFileStream.Create(FileName, fmOpenRead);
Response.ContentStream := FS;
if (Ext = '.html') or (Ext = '.htm') then
begin
Response.ContentType := 'text/html';
end
else
if (Ext = '.css') then
begin
Response.ContentType := 'text/css';
end
else
if (Ext = '.js') then
begin
Response.ContentType := 'text/javascript';
end
else
if (ext = '.txt') then
begin
Response.ContentType := 'text/plain';
end;
end
else
if (Ext = '.jpg') or (Ext = '.jpeg') or (Ext = '.png') or (Ext = '.bmp') or (Ext = '.gif') then
begin
FS := TFileStream.Create(FileName, fmOpenRead);
Response.ContentStream := FS;
end;
end;
上述函数,必须要放在 WebBroker 的默认 Action 里面:
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
S: string;
begin
{--------------------------------------------------------------------------
StandAlone 模式下,作为一个 WebServer,浏览器请求的静态文件,需要直接输出。
如果浏览器没有请求静态文件,则输出动态创建的默认页面给浏览器。
--------------------------------------------------------------------------}
S := Request.PathInfo;
if FileExists(Self.FMyRoot + S) then
begin
Self.HandleFileRequest(Self.FMyRoot + S, Request, Response);
end
else
if S = '/' then
begin
S := '';
S := '<html><head></head><body>这是默认页面</body></html>';
Response.Content := S;
end
else
begin
Response.Content := '';
end;
Handled := True;
end;
当作为 HTTP Server 的 WebBroker 的程序接收到来自浏览器的请求,并且发现这个请求没有对应的 Action 来处理的时候,就会触发这个默认的 Action。然后在这里的代码,检查浏览器请求的文件,是否存在,如果存在,则输出这个文件。
注意:我之前的做法是将图片文件当作流来输出,而文本文件比如 html 和 css 则导入为字符串,然后用 Response.Content := 字符串 的方式。结果在一些比较复杂的页面会出错。主要可能是因为字符编码格式的原因。而直接输出流,反倒就没问题了。
在 StandAlone 模式下,WebBroker 的程序就是一个独立的 EXE,这个 EXE 自己内嵌了一个 HTTP Server,无需额外的 IIS 或者 APACHE 作为 HTTP Server。
在这种情况下,如果浏览器请求一个静态网页,比如 abc.html,WebBroker 程序该如何响应,才能像是 IIS 一样将这个静态网页文件发送给浏览器?如果是 CSS 文件,或者 JavaScript 文件,又该如何响应?
以下代码,我自己测试过,能够正常运行,完全可以把一个 WebBroker 框架的 Delphi 程序当作一个类似 IIS 的 HTTP SERVER 来用。
procedure TWebModule1.HandleFileRequest(const FileName: string; Request: TWebRequest;
Response: TWebResponse);
var
FC, Ext: string;
FS: TFileStream;
SL: TStringList;
begin
{------------------------------------------------------------------------------
处理来自浏览器对静态页面文件的请求:
对于 Stand alone 模式的 WebBroker 程序,这个默认 Action 可以用来当作一个 Web Server 的根:
如果请求的 path 是一个文件,则返回一个文件给客户端。这样,http://ip/WebBroker.exe/abc.html
就可以从这里返回。
------------------------------------------------------------------------------}
if FileExists(FileName) then
begin
//以下代码,测试通过。网页里面有图片链接。网页能够正确显示图片。
Ext := LowerCase(ExtractFileExt(FileName));
if (Ext = '.html') or (Ext = '.htm') or (Ext = '.css') or (Ext = '.js') or (ext = '.txt') then
begin
{-----------------------------------------------------------------------
下载文本文件给浏览器,不能将文本文件加载为字符串然后用字符串返回,
而是应该直接用 Stream 来返回。用字符串返回,可能会有问题。估计原因是文件里面的字符串有些字符的编码有问题导致。
----------------------------------------------------------------------}
FS := TFileStream.Create(FileName, fmOpenRead);
Response.ContentStream := FS;
if (Ext = '.html') or (Ext = '.htm') then
begin
Response.ContentType := 'text/html';
end
else
if (Ext = '.css') then
begin
Response.ContentType := 'text/css';
end
else
if (Ext = '.js') then
begin
Response.ContentType := 'text/javascript';
end
else
if (ext = '.txt') then
begin
Response.ContentType := 'text/plain';
end;
end
else
if (Ext = '.jpg') or (Ext = '.jpeg') or (Ext = '.png') or (Ext = '.bmp') or (Ext = '.gif') then
begin
FS := TFileStream.Create(FileName, fmOpenRead);
Response.ContentStream := FS;
end;
end;
上述函数,必须要放在 WebBroker 的默认 Action 里面:
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
S: string;
begin
{--------------------------------------------------------------------------
StandAlone 模式下,作为一个 WebServer,浏览器请求的静态文件,需要直接输出。
如果浏览器没有请求静态文件,则输出动态创建的默认页面给浏览器。
--------------------------------------------------------------------------}
S := Request.PathInfo;
if FileExists(Self.FMyRoot + S) then
begin
Self.HandleFileRequest(Self.FMyRoot + S, Request, Response);
end
else
if S = '/' then
begin
S := '';
S := '<html><head></head><body>这是默认页面</body></html>';
Response.Content := S;
end
else
begin
Response.Content := '';
end;
Handled := True;
end;
当作为 HTTP Server 的 WebBroker 的程序接收到来自浏览器的请求,并且发现这个请求没有对应的 Action 来处理的时候,就会触发这个默认的 Action。然后在这里的代码,检查浏览器请求的文件,是否存在,如果存在,则输出这个文件。
注意:我之前的做法是将图片文件当作流来输出,而文本文件比如 html 和 css 则导入为字符串,然后用 Response.Content := 字符串 的方式。结果在一些比较复杂的页面会出错。主要可能是因为字符编码格式的原因。而直接输出流,反倒就没问题了。
相关文章推荐
- 文件传送(服务端能响应多个请求)——dosy
- 有些疑惑,一个普通的aspx页面的文件,IIS怎么知道改用 asp.net1.1还是 2.0来解释呢?
- 实现一个Ajax模式的文件上传功能有多难?
- 玩玩AJAX之使用ashx文件响应来自JQuery的JSON请求.
- postgres standalone backend 单用户模式运行
- C# 下面的代码示例演示如何结束异步操作以获取请求的流,然后开始一个请求以获取响应。....
- 仅仅丢失一个普通用户数据文件的恢复A(联机恢复)
- 实现一个Ajax模式的文件上传功能有多难?
- HTTP的请求与响应问题(没有了CSDN,暂时把这里当作论坛了)
- ArcIMS地图配置文件,地图服务,请求和响应之间的关系
- ArcIMS地图配置文件,地图服务,请求和响应之间的关系
- 用一个WEB服务或普通站点 实现这样一个效果?以URL请求,返回一个XML文档
- Chain Of Responsibility 避免把一个请求的发送者和请求者的接收者进行耦合,这个模式要求多个对象都有机会处理这个请求
- 获取HTTP 头中响应请求文件的大小
- 在delphi中如何判断一个文件正在被其它的程序或进程所调用?
- 给自己的Web文件夹增加一个图片或其它文件认证
- 组合设计模式,解决struts只能有一个资源文件的问题
- 我能用Windows PowerShell做什么:删除一个文件或文件夹(或其它输入的目标)
- 请求响应/加密解密时一个需要注意的小问题
- 如何从内核模式设备驱动程序中打开一个文件以及如何读取或写入文件