最近在整理硬盤資料,前幾年收集的不少chm格式的電子書合集,想復制到手機上閱讀,發現格式又不支持,隨即產生了以下作品,寫個web服務器,用來解析電子書,然后就可以隨時隨地不受限制的讀書了。
先看效果
程序很簡單,只有一個exe,一個配置文件。
雙擊運行后,把chm文件解壓后的文件和服務端程序放一起即可。
這里放首頁文件。
下面上代碼
form代碼
object Form1: TForm1
Left = 271
Top = 114
Caption = 'MiniWeb By YSINFO'
ClientHeight = 361
ClientWidth = 795
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OnClose = FormClose
OnCreate = FormCreate
OnShow = FormShow
TextHeight = 13
object Label1: TLabel
Left = 24
Top = 48
Width = 20
Height = 13
Caption = 'Port'
end
object Label2: TLabel
Left = 40
Top = 280
Width = 545
Height = 49
AutoSize = False
Caption = 'Label2'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
end
object ButtonStart: TButton
Left = 24
Top = 8
Width = 75
Height = 25
Caption = 'Start'
TabOrder = 0
OnClick = ButtonStartClick
end
object ButtonStop: TButton
Left = 105
Top = 8
Width = 75
Height = 25
Caption = 'Stop'
TabOrder = 1
OnClick = ButtonStopClick
end
object EditPort: TEdit
Left = 24
Top = 67
Width = 121
Height = 21
TabOrder = 2
Text = '8080'
end
object ButtonOpenBrowser: TButton
Left = 24
Top = 112
Width = 107
Height = 25
Caption = 'Open Browser'
TabOrder = 3
OnClick = ButtonOpenBrowserClick
end
object btnDir: TBitBtn
Left = 224
Top = 112
Width = 107
Height = 25
Caption = #25171#24320#31243#24207#30446#24405
TabOrder = 4
OnClick = btnDirClick
end
object btn1: TBitBtn
Left = 264
Top = 8
Width = 107
Height = 25
Caption = #21047#26032
TabOrder = 5
OnClick = btn1Click
end
object mmo1: TMemo
Left = 504
Top = 8
Width = 185
Height = 169
Lines.Strings = (
'cover.htm'
'index0.htm'
'index1.htm')
TabOrder = 6
end
object btn2: TBitBtn
Left = 510
Top = 192
Width = 139
Height = 25
Caption = #33719#21462#25991#20214#21015#34920
TabOrder = 7
OnClick = btn2Click
end
object ApplicationEvents1: TApplicationEvents
OnIdle = ApplicationEvents1Idle
Left = 288
Top = 24
end
object trycn1: TTrayIcon
PopupMenu = pm1
Visible = True
OnDblClick = trycn1DblClick
Left = 184
Top = 288
end
object pm1: TPopupMenu
Left = 440
Top = 104
object N1: TMenuItem
Caption = #36864#20986
OnClick = N1Click
end
end
object tmr1: TTimer
OnTimer = btn1Click
Left = 424
Top = 264
end
end
PAS代碼
unit FormUnit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.AppEvnts, Vcl.StdCtrls, IdHTTPWebBrokerBridge, Web.HTTPApp, Vcl.Buttons,
Vcl.ExtCtrls, Vcl.Menus;
type
TForm1 = class(TForm)
ButtonStart: TButton;
ButtonStop: TButton;
EditPort: TEdit;
Label1: TLabel;
ApplicationEvents1: TApplicationEvents;
ButtonOpenBrowser: TButton;
btnDir: TBitBtn;
btn1: TBitBtn;
trycn1: TTrayIcon;
Label2: TLabel;
pm1: TPopupMenu;
N1: TMenuItem;
tmr1: TTimer;
mmo1: TMemo;
btn2: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
procedure ButtonStartClick(Sender: TObject);
procedure ButtonStopClick(Sender: TObject);
procedure ButtonOpenBrowserClick(Sender: TObject);
procedure btnDirClick(Sender: TObject);
procedure btn1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure trycn1DblClick(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
FServer: TIdHTTPWebBrokerBridge;
procedure StartServer;
procedure GetData(Sender: TObject);
{ Private declarations }
public { Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
Winapi.ShellApi, Datasnap.DSSession, UnitPublic;
procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
begin
ButtonStart.Enabled := not FServer.Active;
ButtonStop.Enabled := FServer.Active;
EditPort.Enabled := not FServer.Active;
end;
procedure TForm1.GetData(Sender: TObject);
begin
Label2.Caption := Format('調用次數 %s 字節數:%.2f KB 流量:%s 運行時間:%s ', [ncount.ToString, (nsize / 1024), ConvertBytes(nsize), GetSubDateTime(now, dstart)])
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
GetData(Sender);
//Label2.Caption:= Format('調用次數 %s 流量:%s 運行時間:%s ',[ncount.ToString,ConvertBytes(nsize) ,GetSubDateTime(now,dstart) ]) ;
end;
procedure TForm1.btn2Click(Sender: TObject);
var
sl:tstringlist;
begin
sl:=GetAllFile('d:\','*.*');
sl.SaveToFile(AppPath 'd.txt');
sl.Free;
end;
procedure TForm1.btnDirClick(Sender: TObject);
begin
openDir(AppPath);
end;
procedure TForm1.ButtonOpenBrowserClick(Sender: TObject);
var
LURL: string;
begin
StartServer;
LURL := Format('http://192.168.1.13:%s', [EditPort.Text]);
ShellExecute(0, nil, PChar(LURL), nil, nil, SW_SHOWNOACTIVATE);
end;
procedure TForm1.ButtonStartClick(Sender: TObject);
begin
StartServer;
end;
procedure TerminateThreads;
begin
if TDSSessionManager.Instance <> nil then
TDSSessionManager.Instance.TerminateAllSessions;
end;
procedure TForm1.ButtonStopClick(Sender: TObject);
begin
TerminateThreads;
FServer.Active := False;
FServer.Bindings.Clear;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Self.Hide;
Action := caNone;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
EditPort.Text := SetIniNoEn(sconfig, False, 'set', 'port', '8080');
mmo1.Text := SetIniNoEn(sconfig, False, 'set', 'INDEX', 'index.htm');
FServer := TIdHTTPWebBrokerBridge.Create(Self);
StartServer;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
getdata(Sender);
end;
procedure TForm1.N1Click(Sender: TObject);
begin
if MessageDlg('確定退出?', mtConfirmation, mbOKCancel, 0) = mrOk then
Application.Terminate;
end;
procedure TForm1.StartServer;
var
I: Integer;
begin
if not FServer.Active then
begin
FServer.Bindings.Clear;
FServer.DefaultPort := StrToInt(EditPort.Text);
FServer.Active := True;
SetIniNoEn(sconfig, True, 'set', 'port', EditPort.Text);
SetIniNoEn(sconfig, True, 'set', 'INDEX', MMO1.Text);
SetLength(sIndex, mmo1.Lines.Count);
for I := 0 to mmo1.Lines.Count - 1 do
sIndex[I] := mmo1.Lines[I];
end;
end;
procedure TForm1.trycn1DblClick(Sender: TObject);
begin
Self.Show;
end;
end.
unit WebModuleUnit1;
interface
uses
System.SysUtils, System.Classes, Web.HTTPApp, Datasnap.DSHTTPCommon,
Datasnap.DSHTTPWebBroker, Datasnap.DSServer, Datasnap.DSProxyDispatcher,
Datasnap.DSProxyJavaAndroid, Datasnap.DSProxyJavaBlackBerry,
Datasnap.DSProxyObjectiveCiOS, Datasnap.DSProxyCsharpSilverlight,
Datasnap.DSProxyFreePascal_iOS, Datasnap.DSAuth, IPPeerServer,
Datasnap.DSMetadata, Datasnap.DSServerMetadata, Winapi.Windows, uQQWry,
Datasnap.DSClientMetadata, Datasnap.DSCommonServer, Datasnap.DSHTTP, qlog,
UnitPublic;
type
TWebModule1 = class(TWebModule)
DSHTTPWebDispatcher1: TDSHTTPWebDispatcher;
DSProxyGenerator1: TDSProxyGenerator;
DSServerMetaDataProvider1: TDSServerMetaDataProvider;
DSProxyDispatcher1: TDSProxyDispatcher;
procedure WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
procedure WebModuleCreate(Sender: TObject);
private
procedure HandleFileRequest(const FileName: string; Request: TWebRequest; Response: TWebResponse);
{ Private declarations }
public { Public declarations }
end;
var
WebModuleClass: TComponentClass = TWebModule1;
implementation
uses
ServerMethodsUnit1, ServerContainerUnit1, Web.WebReq, MATH;
{$R *.dfm}
function StripHTMLTags(const strHTML: string): string;
var
P: PChar;
InTag: Boolean;
i, intResultLength: Integer;
begin
P := PChar(strHTML);
Result := '';
InTag := False;
repeat
case P^ of
'<':
InTag := True;
'>':
InTag := False;
#13, #10:
; { do nothing }
else
if not InTag then
begin
if (P^ in [#9, #32]) and ((P 1)^ in [#10, #13, #32, #9, '<']) then
else
Result := Result P^;
end;
end;
Inc(P);
until (P^ = #0);
{ convert system characters }
Result := StringReplace(Result, '"', '"', [rfReplaceAll]);
Result := StringReplace(Result, ''', '''', [rfReplaceAll]);
Result := StringReplace(Result, '>', '>', [rfReplaceAll]);
Result := StringReplace(Result, '<', '<', [rfReplaceAll]);
Result := StringReplace(Result, '&', '&', [rfReplaceAll]);
{ here you may add another symbols from RFC if you need }
end;
function getFileType(inputFile: string): string;
const
JPEG_FLAG_BEGIN = $D8FF;
JPEG_FLAG_END = $D9FF;
JPEG_FRAME = $C0FF;
GIF_FLAG_BEGIN = $4947;
GIF_FLAG_END = $3B00;
PNG_FLAG_BEGIN = $5089;
PNG_FLAG_END = $8260;
BMP_FLAG_BEGIN = $4D42;
EXE_FLAG_BEGIN = $5A4D;
ZIP_7Z_FLAG_BEGIN = $7A37;
ZIP_FLAG_BEGIN = $4B50;
var
FileStream: TFileStream;
BeginFlag, EndFlag: WORD;
begin
Result := 'Unkown';
FileStream := nil;
try
FileStream := TFileStream.Create(inputFile, fmOpenRead);
FileStream.Position := 0;
FileStream.Read(BeginFlag, SizeOf(BeginFlag));
FileStream.Position := FileStream.Size - 2;
FileStream.Read(EndFlag, SizeOf(EndFlag));
if (BeginFlag = JPEG_FLAG_BEGIN) and (EndFlag = JPEG_FLAG_END) then
Result := 'JPG';
if (BeginFlag = GIF_FLAG_BEGIN) and (EndFlag = GIF_FLAG_END) then
Result := 'GIF';
if (BeginFlag = PNG_FLAG_BEGIN) and (EndFlag = PNG_FLAG_END) then
Result := 'PNG';
if (BeginFlag = BMP_FLAG_BEGIN) then
Result := 'BMP';
if (BeginFlag = EXE_FLAG_BEGIN) then
Result := 'EXE';
if BeginFlag = ZIP_7Z_FLAG_BEGIN then
Result := '7Z';
if BeginFlag = ZIP_FLAG_BEGIN then
Result := 'Zip';
finally
freeandnil(FileStream);
end;
end;
function getContect(ext: string): string;
begin
if ext[1] = '.' then
ext := Copy(ext, 2);
if ext = 'ez' then
result := 'application/andrew-inset'
else if ext = 'hqx' then
result := 'application/mac-binhex40'
else if ext = 'cpt' then
result := 'application/mac-compactpro'
else if ext = 'doc' then
result := 'application/msword'
else if ext = 'bin' then
result := 'application/octet-stream'
else if ext = 'dms' then
result := 'application/octet-stream'
else if ext = 'lha' then
result := 'application/octet-stream'
else if ext = 'lzh' then
result := 'application/octet-stream'
else if ext = 'exe' then
result := 'application/octet-stream'
else if ext = 'class' then
result := 'application/octet-stream'
else if ext = 'so' then
result := 'application/octet-stream'
else if ext = 'dll' then
result := 'application/octet-stream'
else if ext = 'oda' then
result := 'application/oda'
else if ext = 'pdf' then
result := 'application/pdf'
else if ext = 'ai' then
result := 'application/postscript'
else if ext = 'eps' then
result := 'application/postscript'
else if ext = 'ps' then
result := 'application/postscript'
else if ext = 'smi' then
result := 'application/smil'
else if ext = 'smil' then
result := 'application/smil'
else if ext = 'mif' then
result := 'application/vnd.mif'
else if ext = 'xls' then
result := 'application/vnd.ms-excel'
else if ext = 'ppt' then
result := 'application/vnd.ms-powerpoint'
else if ext = 'wbxml' then
result := 'application/vnd.wap.wbxml'
else if ext = 'wmlc' then
result := 'application/vnd.wap.wmlc'
else if ext = 'wmlsc' then
result := 'application/vnd.wap.wmlscriptc'
else if ext = 'bcpio' then
result := 'application/x-bcpio'
else if ext = 'vcd' then
result := 'application/x-cdlink'
else if ext = 'pgn' then
result := 'application/x-chess-pgn'
else if ext = 'cpio' then
result := 'application/x-cpio'
else if ext = 'csh' then
result := 'application/x-csh'
else if ext = 'dcr' then
result := 'application/x-director'
else if ext = 'dir' then
result := 'application/x-director'
else if ext = 'dxr' then
result := 'application/x-director'
else if ext = 'dvi' then
result := 'application/x-dvi'
else if ext = 'spl' then
result := 'application/x-futuresplash'
else if ext = 'gtar' then
result := 'application/x-gtar'
else if ext = 'hdf' then
result := 'application/x-hdf'
else if ext = 'js' then
result := 'application/x-javascript'
else if ext = 'skp' then
result := 'application/x-koan'
else if ext = 'skd' then
result := 'application/x-koan'
else if ext = 'skt' then
result := 'application/x-koan'
else if ext = 'skm' then
result := 'application/x-koan'
else if ext = 'latex' then
result := 'application/x-latex'
else if ext = 'nc' then
result := 'application/x-netcdf'
else if ext = 'cdf' then
result := 'application/x-netcdf'
else if ext = 'sh' then
result := 'application/x-sh'
else if ext = 'shar' then
result := 'application/x-shar'
else if ext = 'swf' then
result := 'application/x-shockwave-flash'
else if ext = 'sit' then
result := 'application/x-stuffit'
else if ext = 'sv4cpio' then
result := 'application/x-sv4cpio'
else if ext = 'sv4crc' then
result := 'application/x-sv4crc'
else if ext = 'tar' then
result := 'application/x-tar'
else if ext = 'tcl' then
result := 'application/x-tcl'
else if ext = 'tex' then
result := 'application/x-tex'
else if ext = 'texinfo' then
result := 'application/x-texinfo'
else if ext = 'texi' then
result := 'application/x-texinfo'
else if ext = 't' then
result := 'application/x-troff'
else if ext = 'tr' then
result := 'application/x-troff'
else if ext = 'roff' then
result := 'application/x-troff'
else if ext = 'man' then
result := 'application/x-troff-man'
else if ext = 'me' then
result := 'application/x-troff-me'
else if ext = 'ms' then
result := 'application/x-troff-ms'
else if ext = 'ustar' then
result := 'application/x-ustar'
else if ext = 'src' then
result := 'application/x-wais-source'
else if ext = 'xhtml' then
result := 'application/xhtml xml'
else if ext = 'xht' then
result := 'application/xhtml xml'
else if ext = 'zip' then
result := 'application/zip'
else if ext = 'au' then
result := 'audio/basic'
else if ext = 'snd' then
result := 'audio/basic'
else if ext = 'mid' then
result := 'audio/midi'
else if ext = 'midi' then
result := 'audio/midi'
else if ext = 'kar' then
result := 'audio/midi'
else if ext = 'mpga' then
result := 'audio/mpeg'
else if ext = 'mp2' then
result := 'audio/mpeg'
else if ext = 'mp3' then
result := 'audio/mpeg'
else if ext = 'aif' then
result := 'audio/x-aiff'
else if ext = 'aiff' then
result := 'audio/x-aiff'
else if ext = 'aifc' then
result := 'audio/x-aiff'
else if ext = 'm3u' then
result := 'audio/x-mpegurl'
else if ext = 'ram' then
result := 'audio/x-pn-realaudio'
else if ext = 'rm' then
result := 'audio/x-pn-realaudio'
else if ext = 'rpm' then
result := 'audio/x-pn-realaudio-plugin'
else if ext = 'ra' then
result := 'audio/x-realaudio'
else if ext = 'wav' then
result := 'audio/x-wav'
else if ext = 'pdb' then
result := 'chemical/x-pdb'
else if ext = 'xyz' then
result := 'chemical/x-xyz'
else if ext = 'bmp' then
result := 'image/bmp'
else if ext = 'gif' then
result := 'image/gif'
else if ext = 'ief' then
result := 'image/ief'
else if ext = 'jpeg' then
result := 'image/jpeg'
else if ext = 'jpg' then
result := 'image/jpeg'
else if ext = 'jpe' then
result := 'image/jpeg'
else if ext = 'png' then
result := 'image/png'
else if ext = 'tiff' then
result := 'image/tiff'
else if ext = 'tif' then
result := 'image/tiff'
else if ext = 'djvu' then
result := 'image/vnd.djvu'
else if ext = 'djv' then
result := 'image/vnd.djvu'
else if ext = 'wbmp' then
result := 'image/vnd.wap.wbmp'
else if ext = 'ras' then
result := 'image/x-cmu-raster'
else if ext = 'pnm' then
result := 'image/x-portable-anymap'
else if ext = 'pbm' then
result := 'image/x-portable-bitmap'
else if ext = 'pgm' then
result := 'image/x-portable-graymap'
else if ext = 'ppm' then
result := 'image/x-portable-pixmap'
else if ext = 'rgb' then
result := 'image/x-rgb'
else if ext = 'xbm' then
result := 'image/x-xbitmap'
else if ext = 'xpm' then
result := 'image/x-xpixmap'
else if ext = 'xwd' then
result := 'image/x-xwindowdump'
else if ext = 'igs' then
result := 'model/iges'
else if ext = 'iges' then
result := 'model/iges'
else if ext = 'msh' then
result := 'model/mesh'
else if ext = 'mesh' then
result := 'model/mesh'
else if ext = 'silo' then
result := 'model/mesh'
else if ext = 'wrl' then
result := 'model/vrml'
else if ext = 'vrml' then
result := 'model/vrml'
else if ext = 'css' then
result := 'text/css'
else if ext = 'html' then
result := 'text/html;charset=GB2312'
else if ext = 'htm' then
result := 'text/html;charset=GB2312' // Response.ContentType := 'text/html;charset=GB2312';'
else if ext = 'asc' then
result := 'text/plain'
else if ext = 'txt' then
result := 'text/plain'
else if ext = 'rtx' then
result := 'text/richtext'
else if ext = 'rtf' then
result := 'text/rtf'
else if ext = 'sgml' then
result := 'text/sgml'
else if ext = 'sgm' then
result := 'text/sgml'
else if ext = 'tsv' then
result := 'text/tab-separated-values'
else if ext = 'wml' then
result := 'text/vnd.wap.wml'
else if ext = 'wmls' then
result := 'text/vnd.wap.wmlscript'
else if ext = 'etx' then
result := 'text/x-setext'
else if ext = 'xsl' then
result := 'text/xml'
else if ext = 'xml' then
result := 'text/xml'
else if ext = 'mpeg' then
result := 'video/mpeg'
else if ext = 'mpg' then
result := 'video/mpeg'
else if ext = 'mp4' then
result := 'video/mpeg'
else if ext = 'mpe' then
result := 'video/mpeg'
else if ext = 'qt' then
result := 'video/quicktime'
else if ext = 'mov' then
result := 'video/quicktime'
else if ext = 'mxu' then
result := 'video/vnd.mpegurl'
else if ext = 'avi' then
result := 'video/x-msvideo'
else if ext = 'movie' then
result := 'video/x-sgi-movie'
else if ext = 'ice' then
result := 'x-conference/x-cooltalk';
end;
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就可以從這里返回。
------------------------------------------------------------------------------ }
try
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
// sl:=TStringList.Create;
// SL.LoadFromFile(FileName);
Response.ContentType := 'text/html;charset=GB2312';
// Response.Content:=SL.Text;
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;
Response.ContentType := getContect(Ext);
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;
// Response.ContentType := 'image/' Ext;
Response.ContentType := getContect(Ext);
end
else
begin
FS := TFileStream.Create(FileName, fmShareDenyNone);
Response.ContentStream := FS;
Response.ContentType := getContect(Ext);
end
end;
except
on e: Exception do
Logs.Post(llError, e.Message);
end;
end;
function FormatByteSize(const bytes: LongInt): string;
const
B = 1; //byte
KB = 1024 * B; //kilobyte
MB = 1024 * KB; //megabyte
GB = 1024 * MB; //gigabyte
begin
if bytes > GB then
result := FormatFloat('#.## GB', bytes / GB)
else if bytes > MB then
result := FormatFloat('#.## MB', bytes / MB)
else if bytes > KB then
result := FormatFloat('#.## KB', bytes / KB)
else
result := FormatFloat('#.## bytes', bytes);
end;
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
S, slog,slocal: string;
SL: TStringList;
i: Integer;
begin { --------------------------------------------------------------------------StandAlone 模式下,
作為一個 WebServer,瀏覽器請求的靜態文件,需要直接輸出。如果瀏覽器沒有請求靜態文件,則輸出動態創
建的默認頁面給瀏覽器。-------------------------------------------------------------------------- }
try
try
ncount := ncount 1;
// slocal:= getlocal(Request.RemoteIP);
slog := Format('count=%s ,RemoteIP=%s,%s,Request.URL=%s,Request.Method=%s ,Request.Content=%s ,Request.PathInfo=%s',
[ncount.ToString, Request.RemoteIP,slocal, Request.URL, Request.Method, Request.Content, Request.PathInfo]);
Logs.Post(llMessage, slog);
// Logs.Post(llMessage, ncount.ToString ': Request.PathInfo=' Request.PathInfo);
// 獲取文件名 http://localhost:8080/asdf.js?a=123&b=666
// Logs.Post(llMessage, 'Request.Query=' Request.Query); // 獲取參數
// Logs.Post(llMessage, 'Request.Content=' Request.Content);
// for i := 0 to Request.QueryFields.Count - 1 do // 取數數個數
// begin
// Logs.Post(llMessage, Format('Request.QueryFields[%s]', [i.ToString])
// Request.QueryFields[i]); // 取單個參數
// end;
S := Request.PathInfo;
if FileExists(AppPath S) then
begin
Self.HandleFileRequest(AppPath S, Request, Response);
nsize := FileSizeEx(AppPath S) nsize;
Logs.Post(llMessage, '已發送流量:' (nsize / 1024).ToString ' KB ' ConvertBytes(nsize));
end
else if S = '/' then
begin
for I := Low(sindex) to High(sindex) do
if FileExists(AppPath '/' sIndex[I]) then
begin
SL := TStringList.Create;
// SL.LoadFromFile(AppPath '/cover.htm');
SL.LoadFromFile(AppPath '/' sIndex[I]);
Response.ContentType := 'text/html;charset=GB2312';
S := '';
S := '<html><head></head><body>這是默認頁面</body></html>';
Response.Content := SL.Text;
SL.Free;
Break;
end;
end
else
begin
for I := Low(sindex) to High(sindex) do
if FileExists(AppPath '/' sIndex[I]) then
begin
SL := TStringList.Create;
// SL.LoadFromFile(AppPath '/cover.htm');
SL.LoadFromFile(AppPath '/' sIndex[I]);
Response.ContentType := 'text/html;charset=GB2312';
S := '';
S := '<html><head></head><body>這是默認頁面</body></html>';
Response.Content := SL.Text;
SL.Free;
Break;
end ;
// Response.Content := '';
// SL := TStringList.Create;
// SL.LoadFromFile(AppPath '/index.htm');
// Response.ContentType := 'text/html;charset=GB2312';
// S := '';
// S := '<html><head></head><body>這是默認頁面</body></html>';
// Response.Content := SL.Text;
// SL.Free;
end;
except
on e: Exception do
Logs.Post(llMessage, e.Message);
end;
finally
Handled := True;
end;
end;
// procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
// Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
// var
// i: Integer;
// S, sname: string;
// SL: TStringList;
// myst: TMemoryStream;
// begin
//
// try
//
// try
//
// Logs.Post(llMessage, 'Request.PathInfo=' Request.PathInfo);
// // 獲取文件名 http://localhost:8080/asdf.js?a=123&b=666
//
// Logs.Post(llMessage, 'Request.Query=' Request.Query); // 獲取參數
// Logs.Post(llMessage, 'Request.Content=' Request.Content);
// for i := 0 to Request.QueryFields.Count - 1 do // 取數數個數
// begin
// Logs.Post(llMessage, Format('Request.QueryFields[%s]', [i.ToString])
// Request.QueryFields[i]); // 取單個參數
// end;
//
// SL := nil;
// myst := nil;
//
// SL := TStringList.Create;
// myst := TMemoryStream.Create;
//
// S := Request.PathInfo;
// sname := AppPath S;
//
// if FileExists(sname) then
// begin
//
// if getFileType(sname) <> 'Unkown' then
//
// begin
// myst.LoadFromFile(sname);
// Response.ContentStream := myst;
//
// Response.SendResponse;
// end
// else
//
// begin
// SL.LoadFromFile(AppPath '/index.htm');
//
// Response.ContentType := 'text/html;charset=GB2312';
// // 解決 Response 返回中文亂碼問題
// Response.Content := SL.Text;
// end;
//
// end
// else
//
// begin
// if S = '/' then
//
// begin
// SL.LoadFromFile(AppPath '/index.htm');
//
// Response.ContentType := 'text/html;charset=GB2312';
// // 解決 Response 返回中文亂碼問題
// Response.Content := SL.Text;
// end;
//
// end;
// except
// on e: Exception do
// Logs.Post(llError, e.Message);
//
// end;
//
// // Response.Content := '<html><heading/><body>DataSnap Server</body></html>';
//
// finally
// myst.Free;
// SL.Free;
// end;
//
// end;
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
DSServerMetaDataProvider1.Server := DSServer;
DSHTTPWebDispatcher1.Server := DSServer;
if DSServer.Started then
begin
DSHTTPWebDispatcher1.DbxContext := DSServer.DbxContext;
DSHTTPWebDispatcher1.Start;
end;
end;
initialization
SetDefaultLogFile(AppPath 'log\applog.txt', 1024 * 1024 * 20, False, True);
finalization
Web.WebReq.FreeWebModules;
end.
好的,代碼就到這里結束。
如果對你有幫助請關注下我,持之以恒的寫delphi。
, 以上就是delphi爬蟲框架(自己動手豐衣足食)的內容,下面小編又整理了網友對delphi爬蟲框架(自己動手豐衣足食)相關的問題解答,希望可以幫到你。delphi能寫網絡爬蟲嗎?
能寫。相比Python來說麻煩不少,也沒有大量的成熟框架支持。 能寫。相比Python來說麻煩不少,也沒有大量的成熟框架支持。
最近爬蟲工具老是出問題,有沒有其他采數據的工具?
通過易語言去寫爬蟲工具,如電商平臺采集,很多都是易語言寫的,當然也有vb,delphi,java等寫的桌面軟件。 2.python 直接用python寫,不管是爬網頁還是抓數據,。 后。
python能做軟件開發嗎?怎么樣?
應用實在太多,幾乎每個人學習爬蟲之后都能夠通過爬蟲去做一些好玩有趣有用的事。 例子:爬取網絡上的歌曲 3、人工智能 人工智能是現在非常火的一個方向,AI熱潮。
一直做java企業開發,現在自己創業了,感覺java開發太慢了,有沒有好工具?
俗話說,工欲善其事,必先利其器。不過初學時候不大建議過度依賴IDE等過多工具,這會讓自己的編程基礎功變得很差,比如各種語法的不熟悉,各種關鍵字比如synchro。 E。
如何快速學習編程?有哪些學習方法?
這里又牽扯到數據庫原理相關的知識。 遇到一些比較難處理的網站,比如有驗證碼識別該怎么辦呢?其實對于很多純數字和字母的驗證碼都很好解決,自己用深度學習訓。
有沒有簡單易學的編程語言?最好是現在比較火,實用一點的?
剛好自己就是程序員,現在告訴你一些真實的市場需求。PHP PHP作為曾經世界上最好的編程語言,現在仍然是很多中小互聯網公司的首選,特別是一些外包公司、沒有很。
常用的編程語言都有哪些?怎樣做才能更快地入門?
去年,我在網絡上讀過這樣一段文字:“代碼其實是存儲在存儲器(內存、硬盤或者閃存等)中有序電壓高低,編譯出的結果還是電腦中存儲的有序電壓高低。從代碼的編。 5。
Python編程語言未來應用領域在什么方面?
自 1997 年,NASA 就大量使用 Python 進行各種復雜的科學運算。 并且,和其它解釋型語言(如 shell、js、PHP)相比,Python 在數據分析、可視化方面有相當完善和。
Python和java二選一該學哪個?
按照自己的戰略計劃走就行了;在編程行業,興趣永遠是第一位的,做著自己。 我發現,在任何平臺上,語言之爭,幾乎都是一個永恒的話題。 我覺得題主的糾結很沒有道理。