完整API参考、部署指南、常见问题
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/ # 临时文件目录(自动清理)
SrvConfig.ini 核心配置:
Port=8833 # 运行端口
CORS=1 # 是否允许跨域
GZip=1 # 是否启用Gzip压缩
UpDir=.\Uploads # 文件上传路径
可使用 nssm 将 webpascal.exe 注册为Windows服务。
完全兼容Delphi原生语法:
模块化:include('common.api');
// 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);WebPascal 5 内置HTTP客户端,支持常用请求方法,示例如下:
var getResult := http.get('https://api.example.com/users?id=123', '', '');
writeln(getResult);var postResult := http.post('https://api.example.com/users', '', 'name=张三&age=18');
writeln(postResult);var jsonData := '{"name":"张三","age":18}';
var jsonResult := http.json('https://api.example.com/users', '', jsonData);
writeln(jsonResult);var putResult := http.put('https://api.example.com/users/123', '', 'name=李四');
writeln(putResult);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> 配置块。
调度模式说明:
"10" 表示每10秒执行一次yyyyMMddHHmmss,如 "20180520000000" 表示2018年5月20日0点执行MMddHHmmss,如 "0520000000" 表示每年5月20日0点执行ddHHmmss,如 "20000000" 表示每月20日0点执行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 URLQRCode('https://webpascal.com', 80, 2)Now, FormatDateTime, UnixTime, LocalDateTimeToUnixTime, UnixTimeToLocalDateTimeSnowflake(1,2) 生成唯一IDByteSizeToStr(1024^3) → 1GiB;FormatCapacity(1024^3) → 1.07GBvar 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/ 下。
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 脚本无法访问,提示"404 Not Found" | 脚本路径错误、后缀不正确、编码不是UTF-8 | 确认脚本在script目录,后缀与访问的相同,编码为UTF-8无BOM,访问地址格式正确 |
| 无返回值,提示"200 OK" | 脚本未输出任何内容 | 做内容输出,或用try..except..end;捕获异常 |
| 数据库连接失败,提示"无法连接服务器" | 数据库服务未启动、连接字符串参数错误 | 启动数据库服务,检查连接字符串中的主机、端口、用户名、密码是否正确 |
| 计划任务不执行 | 脚本不在task目录、<task>配置块格式错误、服务未启动 | 将脚本移至task目录,检查配置块格式,确保框架服务正常运行 |
| 文件上传失败 | 上传路径无权限、文件过大、前端enctype属性错误 | 给uploads目录添加写入权限,检查文件大小,前端form标签添加enctype="multipart/form-data" |
| 脚本执行报错,提示"未定义标识符" | 语法错误、函数名拼写错误、未引入相关脚本 | 检查脚本语法,确认函数名正确,必要时引入相关公共脚本 |
writeln(内容):输出内容到页面,支持HTML、JSON、文本include('路径'):引入其他脚本文件logger.级别(内容):输出日志,级别为debug/info/warn/error/fataldb.conn(连接名, 连接配置字符串):连接数据库db.query(连接名, SQL语句, 参数...):查询操作,返回JSON结果,有datadb.exec(连接名, SQL语句, 参数...):增删改操作,返回JSON结果,有rowcounthttp.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 JSONhttp.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/ 路径captcha(内容, 品质):生成验证码QRCode(内容, 品质, 放大倍数):生成二维码FormatCapacity(字节数):存储、传输容量格式化,GB=1000MByteSizeToStr(字节数):内存、文件容量格式化,GB=1024MSnowflake(数据中心, 机位):生成分布式唯一ID,参数分别为0..31值