在 URL 中放 # 是出于什么考虑? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kehr
V2EX    问与答

在 URL 中放 # 是出于什么考虑?

  •  2
     < href="Javascript:" Onclick="downVoteTopic(203337);" class="vote">
  •   kehr 2015-07-04 20:05:00 +08:00 6345 次点击
    这是一个创建于 3808 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天发现网页版网易云音乐分享歌单 http://music.163.com/#/share/35255916/90382499
    路径里有个#,之前也遇到过类似的情况。网上搜了一圈,都被导向锚点的解释去了,显然不是我想要的答案。

    于是我用 Tornado 测试了一下:

    class Application(tornado.web.Application): def __init__(self): """""" handlers = [ (r"/", IndexHandler), (r"/#/test", TestHandler), 
    class TestHandler(BaseHandler): def get(self): self.write("可以访问!") 

    Server 地址是: http://localhost:8090

    结果如下:
    1. 访问 http://localhost:8090/#/test 返回的是首页
    2. 修改代码

    class Application(tornado.web.Application): def __init__(self): """""" handlers = [ (r"/", IndexHandler), (r"/test", TestHandler), 

    访问 http://localhost:8090/test,确认服务正常,可以返回预期页面。

    那么很显然了:# 放在 URL 中虽然看起来像是一级路径,但还是起到锚点的作用。浏览器会自动把 # 及其以后的整体部分识别为锚点(猜测)。

    随之问题来了:

    为什么现在开发要用采用这种方案呢?是考虑抓取问题么?

    这个问题困扰我一段时间了,公司内部也有两个平台是这么做的(显然和抓取没毛线关系)。问了一圈貌似也没人知道。

    求指导 _

    21 条回复    2015-07-04 23:53:53 +08:00
    TakanashiAzusa
        1
    TakanashiAzusa  
       2015-07-04 20:08:09 +08:00   3
    利用的是html5的history api,这个阮一峰有文章讲过(虽然我还没吃透。)
    主要应该是出于用户体验的考虑
    http://www.ruanyifeng.com/blog/2011/03/url_hash.html
    MForever78
        2
    MForever78  
       2015-07-04 20:08:32 +08:00
    前端路由而已。
    nealnote
        3
    nealnote  
       2015-07-04 20:19:13 +08:00   3
    理解url标准或者说规范 rfc 1808
    http://www.w3.org/Addressing/rfc1808.txt
    # 后面是页面内标识符,并不会提交给服务器

    这里被用作web app 的路由,打开页面加载一次,其他操作大部分都是页面局部刷新了,不用重新去服务器获取整个页面所有元素
    kehr
        4
    kehr  
    OP
       2015-07-04 20:20:43 +08:00
    @TakanashiAzusa Thanks

    和不在URL里用 # 感觉起来差不多,还增加了处理 HTTP 请求的复杂性。
    但是这么做增加的是哪方面的用户体验呢?
    gongpeione
        5
    gongpeione  
       2015-07-04 20:24:19 +08:00
    前端路由+1
    切换#后面的内容页面不会刷新
    然后js可以通过window.location.hash获取#后面内容 然后就可以ajax之类的了
    Tink
        6
    Tink  
    PRO
       2015-07-04 20:25:40 +08:00 via iPhone
    前端路由
    TakanashiAzusa
        7
    TakanashiAzusa  
       2015-07-04 20:26:21 +08:00   1
    @kehr 这样可以通过ajax提交,页面就不需要跳转了,所谓的单页面应用。另外不跳转的话不需要刷新服务器资源,也可以减少服务器压力。由于这个我不是太怎么了解,就不多说了,给你两个链接参考下。
    http://codecampo.com/topics/84
    http://www.zhihu.com/question/26907726
    kehr
        8
    kehr  
    OP
       2015-07-04 20:27:27 +08:00
    @nealnote 谢谢!我有点明白了。

    这种方式全部 Ajax 也能做。用 # 再结合 Ajax 做也是个不错的方案。

    ![]( )
    weizhenye
        9
    weizhenye  
       2015-07-04 20:30:06 +08:00   1
    个人猜测. 网易音乐要做到切换页面但不中断播放, 可以采用 Pjax. 但又要兼容不支持 History API 的浏览器, 于是就用 # 了
    hellogmh
        10
    hellogmh  
       2015-07-04 20:35:06 +08:00   2
    F12看music.163.com的JS代码,注释里面写得很清楚
    //获取URL path 之后的所有内容,并将/#/替换成/m/使之成为path的一部分
    ksc010
        11
    ksc010  
       2015-07-04 20:49:14 +08:00
    这样做的话可以保证页面不刷新
    url有变化
    并且有历史记录(可前进倒退)
    前端js可感知
    jasontse
        12
    jasontse  
       2015-07-04 20:57:44 +08:00 via Android
    wsph123
        13
    wsph123  
       2015-07-04 21:21:05 +08:00
    前端路由 ,hash 可以做到兼容 IE6+
    min
        14
    min  
       2015-07-04 21:43:53 +08:00 via iPhone
    spa 页内导航
    learnshare
        15
    learnshare  
       2015-07-04 22:08:16 +08:00   1
    单页应用使用 URL 的一种方式,1 是可以确保历史记录正确,2 是可以在 URL 中保留一些参数,供 JS 调用
    也有一些不会用 #,两种还是有一些差别的

    Angular.js 相关的介绍 https://docs.angularjs.org/guide/$location
    kn007
        16
    kn007  
       2015-07-04 22:40:04 +08:00
    mark
    Phariel
        17
    Phariel  
       2015-07-04 22:43:49 +08:00
    我厂就使用此方法,前端路由,单页面应用,可记住所有状态,history back可用。
    sneezry
        18
    sneezry  
       2015-07-04 23:04:53 +08:00
    单页面应用设计,Single Page Application,这样页面渲染可以交给前端来完成,后端只负责数据传输,通常用JSON和XML进行数据格式化
    Biwood
        19
    Biwood  
       2015-07-04 23:15:13 +08:00
    网易云音乐这个是非常特殊的单页应用(SPA),他们不是用 AJAX 而是用 iframe,他们的页面内容全部都是嵌套在一个 iframe 里面,只有页面底下的播放器在 iframe 之外,这是为了使得用户浏览内容的时候不会刷新正在播放的歌曲。

    至于#后面的部分数据,其实就是 iframe 指向的地址,他们监听了 hash 的变化,每次 hash 发生变化时就把地址赋值给 iframe 的 src,以实现页面的跳转。你可以右键查看他们的页面源代码,直接就能找到那段监听 hash 值变化的代码。
    Biwood
        20
    Biwood  
       2015-07-04 23:22:12 +08:00
    网易云音乐的 hash 的使用属于特殊案例,而一般的锚点都是用来指向页面上的某一个片段的,这样能够精确定位到页面上的某一部分内容,比如很多技术文档的二级标题前面都有一个可以点击的链条图标,这个就是为了方便用户复制链接并分享该片段,当别人点击这个链接时可以在打开网页后直接跳到该片段,而不是停留在网页的顶部,类似这种链接: https://help.github.com/articles/set-up-git/#setting-up-git
    dallaslu
        21
    dallaslu  
       2015-07-04 23:53:53 +08:00
    如果把网易云音乐的网址中的 # 去掉,是可以访问的,不过会被重新定位到带 # 的链接上。可以访问的页面是单个歌曲的信息,带 # 号的页面是一个播放器框架,使用 iframe 引用了单曲页。

    一个播放器,是典型的单页应用,所以用这种方案会有楼上所说的各种好处。

    有人提到 history api,可以先去了解一下 PJAX。进一步可以了解一下类似 twitter 中在 url 里加入 !# 的原因。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     895 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 19:58 PVG 03:58 LAX 11:58 JFK 14:58
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86