易语言做POST上传,卡住90%的人的不是HTTP本身,而是"拼不对请求体、拿不到返回、读回来还是乱码"这三件事。把这三件事拆开看,其实都指向同一个解法:找一个只认JSON、不逼你装组件、不逼你建数据库的接口,然后用易语言的"网页_访问"老老实实把body发出去。这篇就用云递数据的推送/读取两个接口,把易语言存取云端数据这条链路走一遍,代码可以直接复制进易语言里跑。
易语言软件想把数据存到云端,难在哪?
先说结论:难的不是"发请求",是"发完请求之后数据落在哪、怎么拿回来、拿回来怎么解析"。很多易语言程序员的第一次云端尝试是这样的——找台服务器,装个MySQL,写个PHP接收脚本,然后发现易语言这边要装数据库连接组件、要处理字符集、要防注入,脚本那边还要配环境。一个本来只想存几条配置或一批采集结果的小需求,硬生生做成了运维项目。
第二个坑是数据形态。易语言原生对JSON的支持一直不算顺手,老程序里大量数据就是一段文本、一行记录、一个用分隔符拼起来的字符串。如果云端接口只接受严格的JSON对象,那老程序要么改造,要么放弃。第三个坑是"读回来":不少自建方案写完就完了,读取要自己写查询、自己写分页、自己维护已读标记,稍微并发一下就重复下发。
所以选型标准其实很朴素:接口要少(少到记不住都难)、请求体要宽容(JSON和纯文本都能收)、读取要有明确语义(取走就不再重复给)。云递数据这类轻量级存储平台正好卡在这个位置上——不需要买服务器和数据库,两个HTTP接口,任何能发请求的语言都能接,易语言自然也在其中。
云递数据接口原理:一个POST请求就够了
把云端存储想象成一个带编号的投递柜:你往柜子里塞东西(推送),柜子按塞进去的先后顺序排队;取的时候从队头拿(读取),拿走的那条就被标记已读,不会再发给你第二次。这就是FIFO队列式消费,也是云递数据读取接口的核心语义——取走即标记已读,不会重复下发。
两个接口的形态非常对称,都是POST:
| 用途 | 接口地址 | 关键参数 | 返回语义 |
|---|---|---|---|
| 推送数据 | http://你的域名/api/push.php | api_key、dataset、data | 写入成功,自动规范化并计算哈希去重 |
| 读取数据 | http://你的域名/api/pull.php | api_key、dataset,支持分页 | 按写入顺序FIFO下发,取走即已读 |
推送接口的JSON请求体长这样:{"api_key":"你的APIKey","dataset":"数据名","data":要存的数据},其中data可以是对象、数组,也可以直接是一段文本。api_key除了放请求体,也可以用X-Api-Key请求头传。读取接口同样是POST到pull.php,按写入顺序取,支持分页和按数据名读取。
还有一个对老程序特别友好的兼容写法:把?api_key=xxx&dataset=yyy拼在URL上,请求体直接放纯文本,就能存一段文本,不用拼任何JSON。这一点后面第四节会专门演示。
分步实现:易语言POST推送数据到云端
易语言发POST,最省事的做法是用精易模块里的网页_访问,它直接支持指定提交数据和附加协议头。下面这段是推送JSON的完整写法,把域名和密钥换成你自己的即可:
.版本 2
.支持库 spec
.子程序 推送数据, 逻辑型
.局部变量 提交地址, 文本型
.局部变量 提交数据, 文本型
.局部变量 协议头, 文本型
.局部变量 返回字节集, 字节集
.局部变量 返回文本, 文本型
提交地址 = "http://你的域名/api/push.php"
' 请求体是JSON,data字段这里放一个文本
提交数据 = "{""api_key"":""你的APIKey"",""dataset"":""测试数据"",""data"":""第一条云端数据""}"
协议头 = "Content-Type: application/json" + #换行符 + "X-Api-Key: 你的APIKey"
返回字节集 = 网页_访问 (提交地址, 1, 到字节集 (提交数据), , , 协议头, , , , , )
返回文本 = 到文本 (返回字节集)
调试输出 (返回文本)
.如果真 (寻找文本 (返回文本, "成功", , 假) ≠ -1)
返回 (真)
.如果真结束
返回 (假)
几个细节值得说清楚。第一,网页_访问的第二个参数1表示POST,第三个参数是提交数据,必须到字节集转一下,否则中文可能按ANSI编码发出去,服务端解析就乱了。第二,请求头里同时给了Content-Type: application/json,服务端才知道按JSON解析;api_key我在请求体里放了一份、协议头里也放了一份,实际上二者选一即可,新手阶段建议先只用请求体,减少变量。
第三,判断成功不要靠"返回是不是空",要看返回文本里的关键字或状态字段。易语言字符串里双引号要写成两个双引号来转义,这是拼JSON最容易翻车的地方,建议把拼装逻辑单独抽一个子程序,别在主流程里手写大段字符串。
分步实现:易语言读取云端数据与纯文本兼容写法
读取同样是POST,区别在于请求体里不需要data,只需要api_key和dataset。下面这段把取回的内容打印到调试输出:
.版本 2
.支持库 spec
.子程序 读取数据
.局部变量 提交地址, 文本型
.局部变量 提交数据, 文本型
.局部变量 返回文本, 文本型
提交地址 = "http://你的域名/api/pull.php"
提交数据 = "{""api_key"":""你的APIKey"",""dataset"":""测试数据""}"
返回文本 = 到文本 (网页_访问 (提交地址, 1, 到字节集 (提交数据), , , "Content-Type: application/json", , , , , ))
调试输出 (返回文本)
注意这里的行为语义:这条数据被这次请求取走后,就被标记为已读,再调一次pull.php不会重复下发。如果你的业务是"多条数据批量消费",可以在请求体里加分页参数,一次取若干条;如果只是想看看云端有没有数据、不想消费掉,那就去控制台看——控制台能可视化看到条数、容量、已读状态,还能下载、编辑、清空、删除。这点很实用:调试阶段别用pull.php反复试探,容易把数据"试没了"。
再说老程序最关心的兼容写法。假设你有一段拼接好的纯文本(比如用竖线分隔的采集记录),不想碰JSON,那就把参数全放URL上,请求体直接放文本:
.版本 2
.支持库 spec
.子程序 推送纯文本
.局部变量 提交地址, 文本型
.局部变量 返回文本, 文本型
提交地址 = "http://你的域名/api/push.php?api_key=你的APIKey&dataset=老程序数据"
返回文本 = 到文本 (网页_访问 (提交地址, 1, 到字节集 ("2024-05-01|设备A|温度36.5"), , , "Content-Type: text/plain", , , , , ))
调试输出 (返回文本)
这种写法对易语言老项目几乎是零改造:原来写本地txt的那行代码,改成发一个POST就行。数据名(dataset)承担分类管理的职责,不同业务用不同dataset,互不干扰,控制台里还能给数据名加标签备注。
运行效果:控制台看得见的数据去向
代码跑通之后,最直观的验证方式不是看易语言的调试输出,而是登录控制台。推送一次,控制台里对应dataset的条数和容量会变化;点进去能看到具体内容、写入时间和已读状态。再调一次pull.php,那条记录的状态会变成已读,列表里仍在,但不会再被下发——这就是"队列式已读消费"的直观表现。
还有两个行为你在控制台里能观察到。其一是哈希去重:内容完全相同的两条数据,只保留第一条。这意味着你的程序如果因为重试逻辑把同一条数据推了两次,云端不会存两份,省心也省容量。其二是写入时的自动规范化,不同格式的数据进来会被统一整理,读取时形态更稳定。
调试建议:先用手动方式在控制台确认数据名拼写,再跑代码。dataset写错一个字符,代码不报错,数据就进了另一个"抽屉",新手最容易在这里怀疑人生。
常见坑与注意事项
第一类坑是编码。易语言默认字符串是ANSI,提交前务必到字节集,接收返回后到文本,中间不要做多余的编码转换;如果返回里中文是乱码,先检查请求头有没有声明UTF-8,再检查你本地是不是用了GBK的文本常量。
第二类坑是引号。手拼JSON时,字段名和字符串值都要用双引号,易语言里写成两个连续双引号。字段名写错、少个逗号、中文标点混进去,服务端解析失败但HTTP状态可能仍是200,所以判断成功要看返回内容而不是只看有没有返回。
第三类坑是消费语义。pull.php取走即已读,这是设计特性不是bug。做定时拉取的程序要考虑到"取了但本地写盘失败"的情况,稳妥做法是先落本地临时文件再标记业务完成,别把云端队列当成本地缓存的替代品。
第四类坑是密钥管理。APIKey等同于你云端数据的钥匙,不要硬编码在会分发的程序里,更不要贴到公开论坛。如果要做私有化部署,云递数据本身支持部署到自己的内网或公网服务器(Nginx + PHP + MySQL),数据自主可控,密钥也就完全在你自己手里。另外记住会员规则:新用户注册赠送3天会员试用,月卡19元、年卡99元,卡密充值(YK开头月卡、NK开头年卡),多张可叠加、到期顺延;会员到期后数据保留不删除,只是暂停推送和读取,续费即恢复。
常见问题
易语言POST上传数据时请求体格式写错怎么办?
先别改代码,用最笨的办法定位:把提交数据用调试输出打出来,复制到任意JSON校验工具里看能不能解析。最常见的错是引号没转义、中文逗号、字段名拼错(api_key、dataset、data三个名字一个字都不能差)。如果一时半会儿修不好,直接退到兼容写法——参数放URL、请求体放纯文本,先让链路通起来,再回头修JSON。另外注意HTTP返回200不代表业务成功,要看返回文本里的状态或关键字。
云递数据的读取接口为什么取走就没了?
因为pull.php是队列式已读消费,按写入顺序FIFO下发,取走即标记已读,不会重复下发。这不是数据被删了,控制台里记录还在、状态变成已读而已。所以调试时不要用pull.php反复试探,想看数据直接去控制台看;需要批量消费就加分页参数一次性取够,避免"取一条丢一条"的尴尬。
易语言老程序不想拼JSON,能直接存一段文本吗?
能。用兼容写法:http://你的域名/api/push.php?api_key=你的APIKey&dataset=数据名,请求体直接放你要存的纯文本,Content-Type设成text/plain即可。老程序里原来写本地文件的逻辑基本不用动,把写文件换成发POST就行,数据名用来分类。
APIKey放在请求体里和放在请求头里有什么区别?
功能上没有区别,两种方式云递数据都支持,任选其一即可。请求体里是JSON字段api_key,请求头里是X-Api-Key。实践上的差别在于:放请求头更干净,请求体可以纯粹是业务数据;放请求体对不熟悉自定义请求头的初学者更直观,调试时一眼能看到。无论哪种,都别把密钥写进会对外分发的程序里。
会员到期后已经存到云端的数据会丢吗?
不会。会员到期只是暂停推送和读取,已经存在云端的数据保留不删除,续费后即恢复使用。正式会员月卡19元、年卡99元,卡密充值,多张可叠加、到期顺延;新用户注册还赠送3天会员试用,够你把这篇教程的代码完整跑一遍。
开始使用
本文的代码示例都可以直接在云递数据上运行:注册后即可获得专属 APIKey,在 开发文档 中查看推送、读取接口的完整说明;需要长期使用可以在 会员中心 用卡密开通月卡或年卡;更多实战内容可以浏览技术博客的其他文章。