Quick Start

Get started with WebPascal 5 in 10 minutes.

Step 1: Download & Extract

Download the package from the official website and extract it to any directory.

Step 2: Configure

Edit SrvConfig.ini to set port (default 8833), CORS, GZip, etc.

Step 3: Start Service

Double‑click webpascal.exe; the console shows Server started on port 8833 when successful.

Step 4: First Script

Create script/hello.api with:

// Hello World example
writeln('Hello WebPascal 5!');
writeln('The exclusive web development tool for Delphi developers!');

Access http://localhost:8833/ask/hello.api to see the output.

Directory Structure

WebPascal/
├── script/      # Web scripts (supports multi‑level subdirectories)
├── task/        # Scheduled task scripts (no subdirectories)
├── uploads/     # Uploaded files (auto‑organized by date)
├── www/         # Static resources (HTML/CSS/JS/images)
├── log/         # Logs (auto‑generated by date, 30‑day retention)
└── cache/       # Temporary files (auto‑cleaned)
                    

Installation & Deployment

System Requirements

  • Windows 7+ / Windows Server 2012+ (32/64-bit)
  • CPU ≥1 core, RAM ≥1GB, disk ≥100MB
  • No Delphi IDE required

Configuration

Core settings in SrvConfig.ini:

Port=8833          # Port number
CORS=1             # Enable CORS (1) or disable (0)
GZip=1             # Enable GZip compression (1) or disable (0)
UpDir=.\Uploads    # Upload directory
                    

Run as Windows Service

Use nssm to register webpascal.exe as a Windows service.

Basic Syntax

Fully compatible with Delphi native syntax:

  • Variable declaration: var i: Integer; s: string;
  • Loops: for, while, repeat‑until
  • Conditions: if‑else, case
  • Common functions: writeln, FormatDateTime, IntToStr, Trim
  • Comments: //, { }, (* *)

Modularization: include('common.api');

JSON Handling

// 1. Parse JSON string
var jsonStr := '{"name":"张三","age":18,"gender":"男"}';
var obj := json.parse(jsonStr);

// 2. Get JSON values (support default operator ?? to avoid null errors)
var name := obj.name; // directly get, returns null if key missing
var email := obj.email ?? '未设置'; // return default if key missing

// 3. Modify JSON object
obj.age := int(20);

// 4. JSON object to string
var newJsonStr := json.stringify(obj);
writeln(newJsonStr);
writeln(unicodetoansi(newJsonStr));

// 5. Iterate JSON object
for var i := 0 to obj.length() - 1 do
begin
    writeln(obj.ElementName(i) + ' : ' + obj[i] + ' | ' + obj[i].TypeName());
end;

Encoding Conversions

// 1. URL encode (supports emoji)
var urlStr := 'https://webpascal.com?name=张三😊';
var urlEnStr := urlencode.encode(urlStr);
writeln('URL encoded: ' + urlEnStr);

// 2. URL decode
var urlDeStr := urlencode.decode(urlEnStr);
writeln('URL decoded: ' + urlDeStr);

// 3. Base64 encode
var base64EnStr := base64.encode('WebPascal 5');
writeln('Base64 encoded: ' + base64EnStr);

// 4. Base64 decode
var base64DeStr := base64.decode(base64EnStr);
writeln('Base64 decoded: ' + base64DeStr);

// 5. HEX encode
var hexEnStr := StrToHex('abc测试123');
writeln('HEX encoded: ' + hexEnStr);

// 6. HEX decode
var hexDeStr := HexToStr(hexEnStr);
writeln('HEX decoded: ' + hexDeStr);

Regular Expressions

// 1. Match pattern (e.g., phone number validation)
var phone := '13800138000';
var isPhone := regex.ismatch(phone, '^1[3-9]\\d{9}$');
if isPhone then
    writeln('手机号格式正确')
else
    writeln('手机号格式错误');

// 2. Extract match (e.g., domain from URL)
var url := 'https://webpascal.com/docs';
var domain := regex.match(url, '(?<=https://).*?(?=/)');
writeln('提取的域名:' + domain);

// 3. Replace (replace all digits with *)
var str := 'abc123def456';
var newStr := regex.replace(str, '\\d+', '*');
writeln('替换后:' + newStr);

Database Operations

Connection Configuration

// SQLite
db.conn('mydb', 'DriverID=SQLite;Database=.\sqlite.db');

// MySQL
db.conn('mydb', 'DriverID=MySQL;Server=127.0.0.1;Database=test;User_name=root;Password=123456');

// SQL Server (trusted connection)
db.conn('mydb', 'DriverID=MSSQL;Server=.;Database=test;OSAuthent=Yes');

Query

include('/conn.cfg');

var res := json.parse(db.query('mydb', 'SELECT * FROM tEmployee WHERE FID=:p1 and FClose=:p2', 3, 0));

if res.code = 200 then // 200 indicates success
begin
    writeln('查询到 ' + IntToStr(res.data.length()) + ' 条数据');
    // Iterate result set
    for var i := 0 to res.data.length() - 1 do
    begin
        var user := res.data[i];
        writeln('用户名:' + user.FID + '|' + user.FName + ',级别:' + IntToStr(user.FLevel));
    end;
end
else
begin
    writeln('查询失败:' + res.msg);
end;

Insert/Update/Delete

// Insert
var addRes := json.parse(db.exec('mydb', 'INSERT INTO tEmployee(FName, FLevel) VALUES(:p1, :p2)', '李四', 1));
if addRes.code = 200 then
    writeln('新增成功,影响行数:' + IntToStr(addRes.rowcount))
else
    writeln('新增失败:' + addRes.msg);

// Update
var updateRes := db.exec('mydb', 'UPDATE tEmployee SET FLevel=:p2 WHERE FID=:p1', 3, 2);

// Delete
var deleteRes := db.exec('mydb', 'DELETE FROM tEmployee WHERE FID=:p1', 4);
Must use parameter placeholders :p1 ~ :p18 to prevent SQL injection.

HTTP Client

Built-in HTTP client supports common request methods:

GET Request

var getResult := http.get('https://api.example.com/users?id=123', '', '');
writeln(getResult);

POST Form

var postResult := http.post('https://api.example.com/users', '', 'name=张三&age=18');
writeln(postResult);

POST JSON

var jsonData := '{"name":"张三","age":18}';
var jsonResult := http.json('https://api.example.com/users', '', jsonData);
writeln(jsonResult);

PUT Request

var putResult := http.put('https://api.example.com/users/123', '', 'name=李四');
writeln(putResult);

DELETE Request

var deleteResult := http.delete('https://api.example.com/users/123', '', '');
writeln(deleteResult);

Form Upload (with file)

var uploadResult := http.formdata(
    'https://api.example.com/upload', 
    'Authorization: Bearer token', 
    'filename=file(/local/image.jpg)'
);
writeln(uploadResult);

File Transfer (save to server)

var savedPath := http.getfile('https://example.com/image.jpg');
writeln('<img src="' + savedPath + '">');

Note: http.getfile saves the remote file to the server's uploads directory and returns a /up/... path.

Request with Encoding and Timeout

var result := http.get(
    'https://api.example.com', 
    '', 
    '', 
    'utf8',    // request encoding
    'utf8',    // response encoding
    5000       // timeout in milliseconds
);

Note: Encoding parameter uses 'utf8' (without hyphen).

Scheduled Tasks

Create a script in the task directory and add a <task> configuration block at the top.

Schedule Modes:

  • Mode 0: Cycle by seconds; time is the number of seconds, e.g., "10" means execute every 10 seconds.
  • Mode 1: Fixed date/time; format yyyyMMddHHmmss, e.g., "20180520000000" means execute at 2018-05-20 00:00:00.
  • Mode 2: Yearly; format MMddHHmmss, e.g., "0520000000" means execute every year on May 20 at 00:00:00.
  • Mode 3: Monthly; format ddHHmmss, e.g., "20000000" means execute on the 20th of each month at 00:00:00.
  • Mode 4: Daily; format HHmmss, e.g., "000000" means execute every day at 00:00:00.

Example (per‑second execution):

<task>
{
    "title": "按秒执行任务",
    "mode": 0,
    "time": "10"
}
</task>
logger.info('任务执行中...');

Other mode examples:

// Fixed date/time (2018-05-20 00:00:00)
{"title": "按年月日执行任务","mode": 1,"time": "20180520000000"}

// Yearly (May 20 00:00:00 every year)
{"title": "按月日执行任务","mode": 2,"time": "0520000000"}

// Monthly (20th of each month at 00:00:00)
{"title": "按日执行任务","mode": 3,"time": "20000000"}

// Daily (every day at 00:00:00)
{"title": "按时间执行任务","mode": 4,"time": "000000"}

Debugging: Remove the <task> block and move the script to the script directory to test via URL; after debugging, move it back to task and restore the block.

Built-in Tools

  • Captcha: captcha('1234', 80) returns image data URL
  • QR Code: QRCode('https://webpascal.com', 80, 2)
  • Time handling: Now, FormatDateTime, UnixTime, LocalDateTimeToUnixTime, UnixTimeToLocalDateTime
  • Snowflake ID: Snowflake(1,2) generates unique ID
  • Capacity formatting: ByteSizeToStr(1024^3) → 1GiB; FormatCapacity(1024^3) → 1.07GB

Security & Encryption

JWT Authentication

var token := jwt.encode('mySecretKey', '{"userId":1,"userName":"张三"}', 7);
writeln('生成的令牌:' + token);

if jwt.verify('mySecretKey', token) then
begin
    writeln('令牌验证成功');
    var jwtData := json.parse(base64.decode(regex.match(token, '(?<=\\.).*?(?=\\.)')));
    writeln('<br>' + jwtData);
    writeln('<br>创建: ' + formatdatetime('yyyy-MM-dd hh:nn:ss.zzz', UnixTimeToLocalDateTime(jwtData.iat)));
    writeln('<br>过期: ' + formatdatetime('yyyy-MM-dd hh:nn:ss.zzz', UnixTimeToLocalDateTime(jwtData.exp)));
    if UnixTime > jwtData.exp then
    begin
        writeln('<br><font color=red>已超时!</font>');
        exit;
    end;
end
else
    writeln('令牌验证失败!');

Hash Algorithms

// MD5
var md5Str := hash.hash('123456', hMD5);
writeln('MD5加密:' + md5Str);

// SHA256
var sha256Str := hash.hash('123456', hSHA256);
writeln('SHA256加密:' + sha256Str);

// SM3 (Chinese national standard)
var sm3Str := hash.hash('123456', hSM3);
writeln('SM3加密:' + sm3Str);

Supported hash algorithms: sm3, sha224, sha256, sha384, sha512, sha3_224, sha3_256, sha3_384, sha3_512, sha1, md5. Parameters must be prefixed with h, e.g., hSHA256.

Symmetric Encryption

// AES encryption
var key := '1234567890abcdef'; // key length: 16 for AES-128, 32 for AES-256
var plainText := '敏感数据123';

// Encrypt
var encryptStr := aes.encode(plainText, key, 'CBC'); // mode: CBC or ECB
// Decrypt
var decryptStr := aes.decode(encryptStr, key, 'CBC');
writeln('加密后:' + encryptStr);
writeln('解密后:' + decryptStr);

Supported algorithms: AES, DES, 3DES, SM4; modes: ECB, CBC.

Logging & Debugging

logger.debug('调试信息');
logger.info('普通信息');
logger.warn('警告信息');
logger.error('错误信息');
logger.fatal('致命信息');

Log files are saved in the log/ directory, automatically named by date (e.g., 20260316.log), and retained for 30 days.

Error messages include line and column numbers for easy debugging. Example: {"code":500,"msg":"Script error: Unexpected \"=\" [line 42, column 4]"}

File Upload

The built-in /upload interface requires no coding. HTML form example:

<!DOCTYPE html>
<html>
<body>
<form action="http://localhost:8833/upload" method="post" enctype="multipart/form-data">
    Select file: <input type="file" name="file">
    <input type="submit" value="Upload">
</form>
</body>
</html>

Returns JSON: {"code":200,"data":"/up/20260319/14302512345678.png"}

Files are automatically organized by date in the uploads/ directory.

Version Information

  • Free Edition: Free forever, full functionality, suitable for personal/learning/small projects. Includes free updates and official tutorials/demos.
  • Commercial Edition: One-time purchase, lifetime license, includes full Delphi source code, permanent technical support and upgrades.

Frequently Asked Questions

IssuePossible CauseSolution
Script not accessible, "404 Not Found"Wrong script path, incorrect suffix, encoding not UTF-8Ensure script is in script directory, suffix matches, encoding is UTF‑8 (no BOM), and URL format is correct
No output, but "200 OK"Script did not output anythingAdd writeln statements or use try..except..end
Database connection failed, "Cannot connect to server"Database service not started, incorrect connection stringStart database service, check host, port, username, password in connection string
Scheduled task not runningScript not in task directory, <task> block malformed, service not runningMove script to task, check block syntax, ensure framework is running
File upload failedNo write permission on upload path, file too large, missing enctype in formGrant write permission to uploads, check file size, add enctype="multipart/form-data" to form
Script error, "Undefined identifier"Syntax error, misspelled function name, missing includeCheck syntax, verify function names, include necessary common scripts

API Quick Reference

Basic API

  • writeln(content): Output content to the page (supports HTML, JSON, text)
  • include(path): Include another script file
  • logger.level(content): Output log; levels: debug/info/warn/error/fatal

Database API

  • db.conn(connectionName, connectionString): Connect to database
  • db.query(connectionName, sql, parameters...): Query, returns JSON with data field
  • db.exec(connectionName, sql, parameters...): Insert/update/delete, returns JSON with rowcount field

HTTP Client API

  • http.get(url, header, params, reqEnc, resEnc, timeout): GET request
  • http.post(url, header, params, reqEnc, resEnc, timeout): POST form
  • http.json(url, header, params, reqEnc, resEnc, timeout): POST JSON
  • http.put(url, header, params, reqEnc, resEnc, timeout): PUT request
  • http.delete(url, header, params, reqEnc, resEnc, timeout): DELETE request
  • http.formdata(url, header, params): Form upload (supports files)
  • http.getfile(url): Download remote file to server's uploads, returns /up/... path

Utility API

  • captcha(content, quality): Generate captcha image data URL
  • QRCode(content, quality, scale): Generate QR code image data URL
  • FormatCapacity(bytes): Format storage capacity (1GB = 1000MB)
  • ByteSizeToStr(bytes): Format memory capacity (1GiB = 1024MiB)
  • Snowflake(datacenterId, workerId): Generate unique distributed ID (IDs range 0..31)