请教一个 iOS NSURL 与前端路由的问题

2019-08-02 10:03:54 +08:00
 acumen

遇到一个前端与 Native 上的问题。前端使用 hash 的路由方式,导致 iOS 端去获取参数失败。由于历史原因,部分传参数是通过 url 传递的。

let url = URL(string: "https://www.abc.com?id=123")
let url2 = URL(string: "https://www.abc.com/#/home?id=123")

url?.query	//id=123
url2?.query	//nil

  ///   foo://example.com:8042/over/there?name=ferret#nose
  ///   \_/   \______________/\_________/ \_________/ \__/
  ///    |           |            |            |        |
  ///  scheme     authority       path        query   fragment

稍微看了 URL 的文档,这个没有取到 query 应该是链接不符合 RPC3896 协议导致取 query 失败。如果讲 #/home 路由放到链接的最后面,是可以成功的。有个疑问是像 url2 这种形式的链接只能另写一套解析 query 和路由的方法吗?

5908 次点击
所在节点    iDev
9 条回复
Lax
2019-08-02 10:51:16 +08:00
与 RFC 冲突基本无解,要不然就自己维护一套奇怪的规则。
最好是在遵循 RFC 的前提下去构造 URL,而不是在解析时搞黑科技。
dorentus
2019-08-02 10:52:34 +08:00
确实如你所说,query 取不到因为 url2 根本就没有 query,只有一个 fragment: "/home?id=123"

对前端也是如此,比如在浏览器或者 node.js 里面:

let url = new URL("https://www.abc.com/#/home?id=123")
url.search // => ""
url.hash // => "#/home?id=123"

前端框架也应该是自己去解析的
hauibojek
2019-08-02 10:52:56 +08:00
```
let characters = "#"
var allowedSet = CharacterSet.urlQueryAllowed
allowedSet.remove(charactersIn: characters)
var str = "https://www.abc.com/#/home?id=123"
str = str.addingPercentEncoding(withAllowedCharacters: allowedSet) ?? str
let url = URL(string: str)
print(url?.query) // Optional("id=123")
```
acumen
2019-08-02 11:01:06 +08:00
@dorentus #2 所以各自需要写解析的规则?这样的话为了兼容需要做比较多的 tracky 的方法
@Lax #1 构造出遮掩这样的 url 的原因是前端使用 vue-router 的 hash 路由,并且在 url 上使用 query 传递参数。或者是是不是 vue-router 是不是有规范,不太懂前端哎。

应该也有人会遇到这样的问题吧?想知道有没有比较好的解决方案?甚至是前端与 native 交互的整体架构
acumen
2019-08-02 11:05:05 +08:00
@hauibojek 感谢,这样是可以取到 query 的,但是路由又取不到了。比如我想在 url 上更新 id 的值,需要获取 url 的路由和 query 之后手动更新,再拼接
Lax
2019-08-02 11:05:54 +08:00
先去完整 URL 的 .fragment 得到 ‘/home?id=123 ’,再用后者构造另一个 URL 取 .query。两行代码
acumen
2019-08-02 11:27:47 +08:00
@Lax emmm,这样是可以取到 query,路由 route 我用后者的 path ?,还需要再次拼接好 url。可以是可以,但是感觉比较 tricky
xi_lin
2019-08-02 14:16:33 +08:00
前端为了单页面模式下不刷新,只能用 hash mode 了。其实现在也可以用 history api
一定是 hash mode 的话,你这边截断处理再拼回去吧
Lax
2019-08-02 16:00:35 +08:00
@acumen 前端 vue-router 用 hash 模式的话,我上面的做法在逻辑上是保持一致的。hash 模式只使用 # 后的内容来路由

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/588416

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX