快速入门

10分钟上手WebPascal 5

第一步:下载解压

从官网下载压缩包,解压至任意目录。

第二步:修改配置

编辑 SrvConfig.ini,可修改端口(默认8833)、跨域、Gzip等。

第三步:启动服务

双击 webpascal.exe,控制台显示 Server started on port 8833 即成功。

第四步:第一个脚本

script 目录下创建 hello.api,内容:

// Hello World 示例
writeln('Hello WebPascal 5!');
writeln('Delphi 开发者的 Web 开发专属利器!');

访问 http://localhost:8833/ask/hello.api 查看效果。

目录结构

WebPascal/
├── script/      # Web脚本(支持多级子目录)
├── task/        # 计划任务脚本(不支持子目录)
├── uploads/     # 上传文件(自动按日期分目录)
├── www/         # 静态资源(HTML/CSS/JS/图片)
├── log/         # 日志目录(自动按日期生成,30天清理)
└── cache/       # 临时文件目录(自动清理)
                    

安装部署

环境要求

  • Windows 7+ / Windows Server 2012+ (32/64位)
  • CPU ≥1核,内存 ≥1GB,磁盘 ≥100MB
  • 无需安装Delphi IDE

配置修改

SrvConfig.ini 核心配置:

Port=8833          # 运行端口
CORS=1             # 是否允许跨域
GZip=1             # 是否启用Gzip压缩
UpDir=.\Uploads    # 文件上传路径
                    

后台运行

可使用 nssm 将 webpascal.exe 注册为Windows服务。

基础语法

完全兼容Delphi原生语法:

  • 变量声明:var i: Integer; s: string;
  • 循环:for, while, repeat-until
  • 条件:if-else, case
  • 常用函数:writeln, FormatDateTime, IntToStr, Trim
  • 注释://, { }, (* *)

模块化:include('common.api');

JSON处理

// 1. JSON字符串转对象
var jsonStr := '{"name":"张三","age":18,"gender":"男"}';
var obj := json.parse(jsonStr);

// 2. 获取JSON对象的值(支持默认值操作符??,避免空值报错)
var name := obj.name; // 直接获取,若键不存在返回null
var email := obj.email ?? '未设置'; // 键不存在时返回默认值

// 3. 修改JSON对象的值
obj.age := int(20);

// 4. JSON对象转字符串
var newJsonStr := json.stringify(obj);
writeln(newJsonStr);
writeln(unicodetoansi(newJsonStr));

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

编码转换

// 1. URL编码(支持emoji)
var urlStr := 'https://webpascal.com?name=张三😊';
var urlEnStr := urlencode.encode(urlStr);
writeln('URL编码后:' + urlEnStr);

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

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

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

// 5. HEX编码
var hexEnStr := StrToHex('abc测试123');
writeln('Hex编码后:' + hexEnStr);

// 6. HEX解码
var hexDeStr := HexToStr(hexEnStr);
writeln('Hex解码后:' + hexDeStr);

正则表达式

// 1. 匹配是否符合规则(如手机号校验)
var phone := '13800138000';
var isPhone := regex.ismatch(phone, '^1[3-9]\\d{9}$');
if isPhone then
    writeln('手机号格式正确')
else
    writeln('手机号格式错误');

// 2. 提取匹配内容(如提取URL中的域名)
var url := 'https://webpascal.com/docs';
var domain := regex.match(url, '(?<=https://).*?(?=/)');
writeln('提取的域名:' + domain);

// 3. 字符串替换(替换所有数字为*)
var str := 'abc123def456';
var newStr := regex.replace(str, '\\d+', '*');
writeln('替换后:' + newStr);

数据库操作

连接配置

// 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 (信任连接)
db.conn('mydb', 'DriverID=MSSQL;Server=.;Database=test;OSAuthent=Yes');

查询操作

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表示操作成功
begin
    writeln('查询到 ' + IntToStr(res.data.length()) + ' 条数据');
    // 遍历结果集
    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;

增删改操作

// 新增数据
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);

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

// 删除数据
var deleteRes := db.exec('mydb', 'DELETE FROM tEmployee WHERE FID=:p1', 4);
必须使用参数占位符 :p1 ~ :p18 防止SQL注入。

HTTP客户端

WebPascal 5 内置HTTP客户端,支持常用请求方法,示例如下:

GET请求

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

POST表单

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请求

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

DELETE请求

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

表单上传(支持文件)

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

文件转存(下载到服务器)

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

注:http.getfile 将远程文件转存到服务器的 uploads 目录,返回 /up/... 路径。

带编码和超时的请求

var result := http.get(
    'https://api.example.com', 
    '', 
    '', 
    'utf8',    // 请求编码
    'utf8',    // 响应编码
    5000       // 5秒超时
);

注:编码参数使用 'utf8'(无连字符)。

计划任务

task 目录下创建脚本,头部添加 <task> 配置块。

调度模式说明:

  • 模式0:按秒循环,time为秒数,如 "10" 表示每10秒执行一次
  • 模式1:固定时间,格式为 yyyyMMddHHmmss,如 "20180520000000" 表示2018年5月20日0点执行
  • 模式2:每年执行,格式为 MMddHHmmss,如 "0520000000" 表示每年5月20日0点执行
  • 模式3:每月执行,格式为 ddHHmmss,如 "20000000" 表示每月20日0点执行
  • 模式4:每日执行,格式为 HHmmss,如 "000000" 表示每日凌晨0点执行

示例(按秒执行):

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

其他模式示例:

// 固定时间执行(2018年5月20日0点)
{"title": "按年月日执行任务","mode": 1,"time": "20180520000000"}

// 每年执行(每年5月20日0点)
{"title": "按月日执行任务","mode": 2,"time": "0520000000"}

// 每月执行(每月20日0点)
{"title": "按日执行任务","mode": 3,"time": "20000000"}

// 每日执行(每日凌晨0点)
{"title": "按时间执行任务","mode": 4,"time": "000000"}

调试说明:去掉 <task> 配置块,将脚本移动到 script 目录,可直接通过 URL 访问调试,调试完成后再移回 task 目录并添加配置块。

内置工具集

  • 验证码captcha('1234', 80) 返回图片data URL
  • 二维码QRCode('https://webpascal.com', 80, 2)
  • 时间处理Now, FormatDateTime, UnixTime, LocalDateTimeToUnixTime, UnixTimeToLocalDateTime
  • 雪花算法Snowflake(1,2) 生成唯一ID
  • 容量格式化ByteSizeToStr(1024^3) → 1GiB;FormatCapacity(1024^3) → 1.07GB

安全与加密

JWT身份认证

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('令牌验证失败!');

哈希算法

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

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

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

支持的哈希算法:sm3、sha224、sha256、sha384、sha512、sha3_224、sha3_256、sha3_384、sha3_512、sha1、md5,参数需要加h开头,比如hSHA256。

对称加密

// AES加密
var key := '1234567890abcdef'; // 密钥(AES-128需16位,AES-256需32位)
var plainText := '敏感数据123';

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

支持算法:AES、DES、3DES、SM4,支持ECB/CBC多种加密模式。

日志与调试

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

日志文件保存在 log/ 目录,自动按日期命名(如20260316.log),保留30天自动清理。

错误信息包含行号列号,便于定位。例如:{"code":500,"msg":"Script error: Unexpected \"=\" [line 42, column 4]"}

文件上传

系统内置 /upload 接口,无需编写脚本。HTML表单:

<!DOCTYPE html>
<html>
<body>
<form action="http://localhost:8833/upload" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="file">
    <input type="submit" value="上传">
</form>
</body>
</html>

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

文件自动按日期分目录存储在 uploads/ 下。

版本说明

  • 免费版:永久免费,无功能限制,适用于个人开发、学习测试、小型项目;支持免费版本更新,提供官方教程、演示案例。
  • 商业版:一次性购买源码,终身使用,适用于企业开发、商业项目;包含Delphi完整源码,支持二次开发;提供永久技术支持与版本升级。

常见问题

问题现象可能原因解决方案
脚本无法访问,提示"404 Not Found"脚本路径错误、后缀不正确、编码不是UTF-8确认脚本在script目录,后缀与访问的相同,编码为UTF-8无BOM,访问地址格式正确
无返回值,提示"200 OK"脚本未输出任何内容做内容输出,或用try..except..end;捕获异常
数据库连接失败,提示"无法连接服务器"数据库服务未启动、连接字符串参数错误启动数据库服务,检查连接字符串中的主机、端口、用户名、密码是否正确
计划任务不执行脚本不在task目录、<task>配置块格式错误、服务未启动将脚本移至task目录,检查配置块格式,确保框架服务正常运行
文件上传失败上传路径无权限、文件过大、前端enctype属性错误给uploads目录添加写入权限,检查文件大小,前端form标签添加enctype="multipart/form-data"
脚本执行报错,提示"未定义标识符"语法错误、函数名拼写错误、未引入相关脚本检查脚本语法,确认函数名正确,必要时引入相关公共脚本

常用API速查

基础API

  • writeln(内容):输出内容到页面,支持HTML、JSON、文本
  • include('路径'):引入其他脚本文件
  • logger.级别(内容):输出日志,级别为debug/info/warn/error/fatal

数据库API

  • db.conn(连接名, 连接配置字符串):连接数据库
  • db.query(连接名, SQL语句, 参数...):查询操作,返回JSON结果,有data
  • db.exec(连接名, SQL语句, 参数...):增删改操作,返回JSON结果,有rowcount

HTTP客户端API

  • http.get(url, header, params, reqEnc, resEnc, timeout):GET请求
  • http.post(url, header, params, reqEnc, resEnc, timeout):POST表单
  • http.json(url, header, params, reqEnc, resEnc, timeout):POST JSON
  • http.put(url, header, params, reqEnc, resEnc, timeout):PUT请求
  • http.delete(url, header, params, reqEnc, resEnc, timeout):DELETE请求
  • http.formdata(url, header, params):表单上传(支持文件)
  • http.getfile(url):将远程文件转存到服务器的 uploads 目录,返回 /up/ 路径

工具类API

  • captcha(内容, 品质):生成验证码
  • QRCode(内容, 品质, 放大倍数):生成二维码
  • FormatCapacity(字节数):存储、传输容量格式化,GB=1000M
  • ByteSizeToStr(字节数):内存、文件容量格式化,GB=1024M
  • Snowflake(数据中心, 机位):生成分布式唯一ID,参数分别为0..31值