有用户输入一个看似正常的url信息,接口却一直返回参数不符合规范,于是反馈来询问原因
代码乍一看没什么问题,直接使用的标准包url.Parse
方法去判断,判断条件为解析正确且域名路径不为空
直到看到日志,用户传入的是一个不包含协议的地址,导致解析错误无法获取正确的Host信息
原因
用一段代码来说明问题
1 | func main() { |
Parse
与ParseRequestURI
两个方法的行为不一致上(go 1.17.2)
两个方法的签名及注释信息
1 | // Parse parses a raw url into a URL structure. |
从url字符串中解析scheme的方法
1 | // Maybe rawURL is of the form scheme:path. |
go文档中的说明信息
1 | A URL represents a parsed URL (technically, a URI reference). |
- 从注释信息可知,
Parse
支持相对路径和绝对路径地址的解析,但ParseRequestURI
仅应用作绝对路径地址的解析- 所以 ParseRequestURI 解析 s1 时返回了不正确的信息
Parse
已经注明了不应当尝试解析一个不包含scheme信息的地址,但你这么做并不会得到一个error- 从 getScheme 方法中可知是通过
:
这个字符串来区分的,此前的字符串被认为是 scheme,之后的则是其它路径(结合上面go文档中的正则来看) - parse字符串s1时,scheme 返回了 a.cn 就是这个原因
- 从 getScheme 方法中可知是通过
ParseRequestURI
由于假定被解析的地址是http请求中获取的(主要区别),所以会忽略fragment,原因是浏览器不会发送它- 二者对相对路径/不包含scheme信息的地址均不返回错误,需要自行判断
解决方法
- 按需选择使用,相对路径解析时选择Parse
- 自行封装解析方法以兼容无scheme情况
- 用之前多读读文档