V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
acumen
V2EX  ›  iDev

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

  •  
  •   acumen ·
    acumen1005 · 2019-08-02 10:03:54 +08:00 · 5907 次点击
    这是一个创建于 1976 天前的主题,其中的信息可能已经有所发展或是发生改变。

    遇到一个前端与 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 和路由的方法吗?

    9 条回复    2019-08-02 16:00:35 +08:00
    Lax
        1
    Lax  
       2019-08-02 10:51:16 +08:00
    与 RFC 冲突基本无解,要不然就自己维护一套奇怪的规则。
    最好是在遵循 RFC 的前提下去构造 URL,而不是在解析时搞黑科技。
    dorentus
        2
    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
        3
    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
        4
    acumen  
    OP
       2019-08-02 11:01:06 +08:00
    @dorentus #2 所以各自需要写解析的规则?这样的话为了兼容需要做比较多的 tracky 的方法
    @Lax #1 构造出遮掩这样的 url 的原因是前端使用 vue-router 的 hash 路由,并且在 url 上使用 query 传递参数。或者是是不是 vue-router 是不是有规范,不太懂前端哎。

    应该也有人会遇到这样的问题吧?想知道有没有比较好的解决方案?甚至是前端与 native 交互的整体架构
    acumen
        5
    acumen  
    OP
       2019-08-02 11:05:05 +08:00
    @hauibojek 感谢,这样是可以取到 query 的,但是路由又取不到了。比如我想在 url 上更新 id 的值,需要获取 url 的路由和 query 之后手动更新,再拼接
    Lax
        6
    Lax  
       2019-08-02 11:05:54 +08:00
    先去完整 URL 的 .fragment 得到 ‘/home?id=123 ’,再用后者构造另一个 URL 取 .query。两行代码
    acumen
        7
    acumen  
    OP
       2019-08-02 11:27:47 +08:00
    @Lax emmm,这样是可以取到 query,路由 route 我用后者的 path ?,还需要再次拼接好 url。可以是可以,但是感觉比较 tricky
    xi_lin
        8
    xi_lin  
       2019-08-02 14:16:33 +08:00
    前端为了单页面模式下不刷新,只能用 hash mode 了。其实现在也可以用 history api
    一定是 hash mode 的话,你这边截断处理再拼回去吧
    Lax
        9
    Lax  
       2019-08-02 16:00:35 +08:00
    @acumen 前端 vue-router 用 hash 模式的话,我上面的做法在逻辑上是保持一致的。hash 模式只使用 # 后的内容来路由
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2556 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 05:58 · PVG 13:58 · LAX 21:58 · JFK 00:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.