iOS开发:关于URL解析
iOS与Android对URL的解析
首先分析了一下iOS与Android在解析URL上是否有差异。
iOS的解析:
guard let url = URLComponents(string: "http://www.example.com:80/path/to/resource.html?param=value#fragment") else {
return
}
// 获取协议
let scheme = url.scheme ?? ""
print("url Protocol: " + scheme)
// 获取主机名
let host = url.host ?? ""
print("url Host: " + host)
// 获取端口号
let port = url.port ?? -1
print("url Port: \(port)")
// 获取路径
let path = url.path
print("url Path: " + path)
// 获取查询字符串
let query = url.query ?? ""
print("url Query: " + query)
var dict = [String: String]()
if let queryItems = url.queryItems {
dict = queryItems.toDict
}
print("url dict: \(dict)")
// 获取片段
let ref = url.fragment ?? ""
print("url Ref: " + ref)
/**
url Protocol: http
url Host: www.example.com
url Port: 80
url Path: /path/to/resource.html
url Query: param=value
url Ref: fragment
*/
Android的解析:
import java.net.URL;
import java.net.MalformedURLException;
public class URLParsingExample {
public static void main(String[] args) {
try {
URL url = new URL("http://www.example.com:80/path/to/resource.html?param=value#fragment");
// 获取协议
String protocol = url.getProtocol();
System.out.println("Protocol: " + protocol);
// 获取主机名
String host = url.getHost();
System.out.println("Host: " + host);
// 获取端口号
int port = url.getPort();
System.out.println("Port: " + port);
// 获取路径
String path = url.getPath();
System.out.println("Path: " + path);
// 获取查询字符串
String query = url.getQuery();
System.out.println("Query: " + query);
// 获取片段
String ref = url.getRef();
System.out.println("Ref: " + ref);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
Protocol: http
Host: www.example.com
Port: 80
Path: /path/to/resource.html
Query: param=value
Ref: fragment
小结
其实可以看出,iOS和Android对于URL的解析基本上是一致的。
-
?用于分割前后,前面可以认为是路径,后面的可以认为是参数
-
param=value&name=season,通过=与&用来分割参数
-
最后通过#用来分割Fragment
遇到的异常情况
我们在通过name=value这种形式进行传参的时候,不可避免可能会使用到#与?符号,比如下面:
haha://abcd?param=value&id=12345678&jumpType=information&content=我关注的话题#你好啊?
content=我关注的话题#你好啊?其实是{ content: 我关注的话题#你好啊? }这样一个json,但是会被截取成下面这样子:
url Query: param=value&id=12345678&jumpType=information&content=我关注的话题
url dict: ["id": "12345678", "content": "我关注的话题", "jumpType": "information", "param": "value"]
url Ref: 你好啊
content=我关注的话题#你好啊?
明明是一个完整的参数,但是因为解析的策略,#与?都被截掉了。
思路
为了保证语义的完整性。
我们可以考虑将name=value这种形式进行传参转换为json:{"id": "12345678", "content": "我关注的话题#你好啊?", "jumpType": "information", "param": "value"},然后再转成jsonString,最后使用base64进行加密获得string,这里使用base64进行加密是为了保证加密后的数据没有可以被解析的符号。
App侧拿到后,先将这个string通过base64解密,获得完整的jsonString,然后就可以正常解析了。
例子
这个例子中有jumpType、id、jsonString三个参数,然后jsonString里面包含了很多个参数
nm://home?jumpType=TopicDetail&id=d308e8ff62dbb382a106def90d946759&jsonString=e1widGFsa2luZ05hbWVcIjpcIuaIkeeahOaPkOi9puaXpeiusFwiLFwiaG90UmF0ZVwiOjEyMzgsXCJ2aWV3Q291bnRcIjo0NzY1MixcInN0YXR1c1wiOjF9
解析jsonString
"{\"talkingName\":\"我的提车日记\",\"hotRate\":1238,\"viewCount\":47652,\"status\":1}"
base64加解密会不会出现#?=这个符号呢?
有关与这个,我去查阅了一下资料
在 Swift 中,使用 Base64 编码后的字符串不会包含 ?
、#
或 &
这些符号。Base64 编码的输出只会包含以下字符:
- 大写字母:
A-Z
- 小写字母:
a-z
- 数字:
0-9
- 加号:
+
- 斜杠:
/
- 等号:
=
(用于填充)
这些字符是 Base64 编码标准的一部分,确保编码后的字符串可以安全地在文本环境中传输。
但是会不会出现异常情况呢?这个还真不能保证。
总结
URL解析其实不仅涉及到网络请求,有些路由规则与传参也会涉及到URL的拼接与规则,了解URL的细节,以及多端的异同点,可以提高开发效率。