示例代码均为匿名化改写,用于说明模式;具体网络请求需按应用的数据模型补全。
网络入口集中之后
业务 API 不应重复拼接服务器地址、认证信息和表单编码。统一网络客户端可以集中管理环境选择、传输会话、解码器和请求上下文。功能层通过常见 HTTP 方法以及上传入口提交请求。
请求开始时读取当前认证与位置上下文,按请求类型选择查询参数、表单或 multipart 编码,再统一处理 HTTP 状态和业务响应结构。传输会话可被测试替身替换,使 URL 构造、参数编码与错误映射不必依赖真实网络。
把共享上下文放进 actor,可以减少同时读写环境和身份信息时的竞态。但 actor 不会自动校验请求是否仍属于当前用户:调用方仍需在异步结果返回后校验会话身份。
请求上下文也可以作为一个小值类型,整个读写过程由 actor 隔离:
struct RequestContext: Sendable {
var accessToken: String?
var regionID: String?
}
actor NetworkClient {
private var context = RequestContext()
func updateContext(_ context: RequestContext) {
self.context = context
}
func contextSnapshot() -> RequestContext {
context
}
}
网络层返回数据前仍需校验发起请求时的会话代次;actor 只隔离共享上下文,不会自动判断响应属于哪个账号。网络 actor 保持轻量,只管理请求环境与认证快照,大型图片缓存交给独立组件。
取消策略应由请求表达
大多数页面请求应随页面生命周期取消。少量页面离开后仍需完成的 best-effort 工作,可以显式采用独立取消策略。不要将普通业务请求默认改为脱离调用方生命周期,否则用户离开页面后,网络任务仍可能继续消耗资源或产生副作用。
兼容协议不等于安全边界
遗留接口可能依赖固定排序和旧式摘要算法。若兼容实现中使用的材料编译在客户端,它就不是服务器秘密。认证、资源归属、限流、幂等和业务状态校验仍应在服务端执行。
发布环境还应由构建类型明确决定,并有自动化检查防止 Release 错连测试服务。日志系统若有多条记录路径,应分别验证每条路径的敏感字段脱敏结果。
适用场景
- 多个业务功能共用认证、地区和环境上下文。
- 请求编码和服务端错误协议需要统一维护。
- 希望使用 URLProtocol 或注入会话构建离线网络测试。
