Swift Vapor请求参数加号转空格 如何将+替换为%2B正确解析
问题原因
URL查询参数采用application/x-www-form-urlencoded格式解码时,默认会把+识别为空格的替代字符,这就是你通过req.query.get拿到的密码里加号变成空格的核心原因。
解决方案
方案1:客户端标准编码(推荐)
要求调用方(包括Postman测试时)对password参数做标准URL百分号编码:
- 密码中的
+编码为%2B - 密码中的空格编码为
%20
这种方案符合HTTP规范,服务端不需要做任何代码修改,req.query.get会自动把%2B解码为+,正确保留密码里的加号。
Postman测试时可直接在Params栏的password值里输入%2B代表加号,也可以右键参数值选择「EncodeURIComponent」自动完成编码。
方案2:服务端兼容处理(适配未编码的请求)
如果无法要求客户端修改,服务端可以直接读取原始查询字符串自行解析,避开默认的解码规则,避免+被转成空格,修改后的代码如下:
func routes(_ app: Application) throws { app.get("validate") { req -> Int in do { // 读取原始查询字符串自行解析,不使用默认解码规则 guard let queryStr = req.url.query else { return 400 } let queryItems = queryStr.split(separator: "&") var rawPassword: String? for item in queryItems { let kvPair = item.split(separator: "=", maxSplits: 1) guard kvPair.count == 2, kvPair[0] == "password" else { continue } // 仅处理百分号编码,不将+转换为空格 rawPassword = String(kvPair[1]).removingPercentEncoding break } guard var password = rawPassword else { return 400 } if !isValidPassword(&password) { return 400 } } catch { return 400 } return 200 } }
注意:不要直接把默认解码后的密码里的空格替换为加号,这种方式会把密码中原本的合法空格也误转为加号,导致校验失败。
内容的提问来源于stack exchange,提问作者Veronika Babii
相关产品推荐
相关产品推荐

