普贤教程 › 进阶教程
HTTP 客户端
HTTP 客户端只有两个入口:http_get 拿响应体,http_request 拿到完整响应(状态码、头、体)。
http_get:只要内容
px
var html = http_get("https://cx.dzty.club/") print(type(html)) print(str(len(html) > 0))
text
string
true返回的是响应体字符串,状态码被丢掉。只适合"一定能拿到内容"的场景,比如抓一个公开页面。
http_request:完整响应
px
var r = http_request("https://cx.dzty.club/", "GET", null) print(str(r["status"])) print(str(r["headers"].keys())) print(str(len(r["body"]) > 0))
text
200 [content-type, date, server, ...] true
| 参数 | 说明 |
|---|---|
url | 完整 URL,含 http(s) 前缀 |
method | "GET" / "POST" / "PUT" / "DELETE" |
body | 请求体字符串;GET 传 null |
headers | 可选,字典,如 {"Content-Type": "application/json"} |
返回字典:{"status": int, "headers": dict, "body": string}。
POST JSON
px
var payload = json_stringify({"name": "晨曦", "action": "ping"}) var r = http_request("https://cx.dzty.club/api/v1/ping", "POST", payload, {"Content-Type": "application/json"}) print(str(r["status"]))
text
200Header 大小写请求头的键按习惯写
Content-Type;响应头的键名由服务端决定,读的时候用 r["headers"].has("Content-Type") 判断存在,别假设一定叫某个拼写。Set-Cookie 出现多次时会以 list 形式返回。判读状态码
http_request 不把 4xx / 5xx 当失败——只要拿到响应就返回。业务上要自己判:
px
def fetch_json(url): var r = http_request(url, "GET", null) if r["status"] < 200 or r["status"] >= 300: return Err("HTTP " + str(r["status"])) var parsed = json_parse_opt(r["body"]) if parsed.is_err(): return Err("响应不是 JSON:" + parsed.err()) return Ok(parsed.ok()) var res = fetch_json("https://cx.dzty.club/api/v1/me") if res.is_err(): print(res.err()) else: print("ok")
超时与重试
网络调用必须设上限。默认超时可能很长,写服务时自己包一层重试:
px
def get_with_retry(url, times): var i = 0 var last = "" while i < times: var r = http_request(url, "GET", null) if r["status"] >= 200 and r["status"] < 300: return Ok(r["body"]) last = "HTTP " + str(r["status"]) i += 1 return Err("重试 " + str(times) + " 次仍失败:" + last) print(str(get_with_retry("https://cx.dzty.club/", 2).is_ok()))
text
true并发请求
要同时打多个地址,必须在编译轨用 spawn(解释器不支持并发):
px
# 需 px build 后运行 var ch = chan [dict](3) var urls = ["https://a.example/", "https://b.example/", "https://c.example/"] for u in urls: spawn worker(u, ch) var i = 0 while i < 3: print(str(ch.recv()["status"])) i += 1
与 Ma 托管的接口通信
同一台机器内部调用,走回环地址,别绕到公网域名:
px
var r = http_request("http://127.0.0.1:9536/api/v1/sync/status", "GET", null) print(str(r["status"]))
给请求加标识内部服务之间调用时带上
X-Request-Id,日志里能串起一整条链路;排查"哪个环节慢/错"时省一半时间。常见问题
| 现象 | 原因 |
|---|---|
| 返回体为空 | 服务端 3xx 重定向,客户端不自动跟随 |
| 403 / 406 | 缺 User-Agent 或 Referer,按服务端要求补头 |
| 中文乱码 | 响应头 charset 与实际编码不一致 |
| 偶发超时 | 没有重试;或对端连接池耗尽 |