V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Reign
V2EX  ›  程序员

URL 规范中,问号前面是否要添加斜杠?

  •  
  •   Reign · 2017-09-04 08:55:30 +08:00 · 6747 次点击
    这是一个创建于 2397 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个动态的网址,比如: https://www.v2ex.com?page=2 以及 https://www.v2ex.com/?page=2 这两种网址哪个才是最标准规范的 URL 形式?

    33 条回复    2017-09-04 22:23:10 +08:00
    yulitian888
        1
    yulitian888  
       2017-09-04 08:58:28 +08:00
    scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
    jhaohai
        2
    jhaohai  
       2017-09-04 08:59:43 +08:00 via iPhone
    如果是根的话需要加的吧
    gstqc
        3
    gstqc  
       2017-09-04 08:59:48 +08:00 via iPhone
    第一种不合法
    GTim
        4
    GTim  
       2017-09-04 09:01:53 +08:00 via iPad
    可以不加
    torbrowserbridge
        5
    torbrowserbridge  
       2017-09-04 09:02:07 +08:00
    就算不是根,加与不加也是不一样的。例如:/news/?page=1 与 /news?page=1
    FanWall
        6
    FanWall  
       2017-09-04 09:04:32 +08:00 via Android
    第二种
    我觉得第一种的请求成功是因为浏览器自动补齐成第二种(抓包就会发现)
    以前遇到类似的,第一种的 url 用 WinhttpCrackUrl 解析的话直接报 invalid
    zjsxwc
        7
    zjsxwc  
       2017-09-04 09:05:51 +08:00
    服务端可以区别,url 是""还是"/"来提供不同的内容。 所以 /something 与 /something/ 是 2 个不同的地址
    canbingzt
        8
    canbingzt  
       2017-09-04 09:10:47 +08:00
    @torbrowserbridge 确实,java 里可以通过 @RequestMapping("")和 @RequestMapping("/")测试
    weyou
        9
    weyou  
       2017-09-04 09:11:08 +08:00 via Android   ❤️ 4
    其实 2 种都不规范,只是浏览器做了兼容。rfc1738:
    HTTP
    httpurl = "http://" hostport [ "/" hpath [ "?" search ]]
    hpath = hsegment *[ "/" hsegment ] hsegment = *[ uchar | ";" | ":" | "@" | "&" | "=" ] search = *[ uchar | ";" | ":" | "@" | "&" | "=" ]
    aleung
        10
    aleung  
       2017-09-04 09:23:51 +08:00 via Android
    @weyou 如果是这样,RFC1738 有局限性了:一定要有 hpath,search 才能存在?
    weyou
        11
    weyou  
       2017-09-04 09:27:49 +08:00 via Android
    @aleung rfc 是这样的规定,但是各大浏览器也没有按照这个做,即使没有 hpath 不一样也可以么加 search 么。
    aleung
        12
    aleung  
       2017-09-04 09:33:13 +08:00   ❤️ 6
    @weyou RFC 1738 is updated by RFC 3968.

    ```
    3. Syntax Components

    The generic URI syntax consists of a hierarchical sequence of
    components referred to as the scheme, authority, path, query, and
    fragment.

    URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

    hier-part = "//" authority path-abempty
    / path-absolute
    / path-rootless
    / path-empty

    The scheme and path components are required, though the path may be
    empty (no characters). When authority is present, the path must
    either be empty or begin with a slash ("/") character. When
    authority is not present, the path cannot begin with two slash
    characters ("//"). These restrictions result in five different ABNF
    rules for a path (Section 3.3), only one of which will match any
    given URI reference.

    The following are two example URIs and their component parts:

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

    3.3 Path

    path = path-abempty ; begins with "/" or is empty
    / path-absolute ; begins with "/" but not "//"
    / path-noscheme ; begins with a non-colon segment
    / path-rootless ; begins with a segment
    / path-empty ; zero characters
    ```

    因此,https://www.v2ex.com?page=2 以及 https://www.v2ex.com/?page=2 这两种网址都符合规范。
    aleung
        13
    aleung  
       2017-09-04 09:33:49 +08:00
    还有,是否支持是看服务端,跟浏览器没有关系。
    anyforever
        14
    anyforever  
       2017-09-04 09:35:25 +08:00
    楼主得补点基础知识啊。
    aleung
        15
    aleung  
       2017-09-04 09:42:30 +08:00 via Android
    不好意思,输入错了,是 rfc 3986
    Mss
        16
    Mss  
       2017-09-04 09:47:21 +08:00
    不加斜杠请求会出现 301
    weyou
        17
    weyou  
       2017-09-04 09:49:46 +08:00 via Android
    @aleung 受教,刚才查的时候没发现还有个更新过的协议。
    doubleflower
        18
    doubleflower  
       2017-09-04 10:46:56 +08:00
    @Mss 搞笑吧
    zzNucker
        19
    zzNucker  
       2017-09-04 10:55:18 +08:00
    规范和实现一向差距挺远的
    Tink
        20
    Tink  
       2017-09-04 11:03:56 +08:00 via iPhone
    @Mss 你在逗我
    zjp
        21
    zjp  
       2017-09-04 11:27:09 +08:00 via Android
    @Tink
    @doubleflower 对于主机不是吗,请求 v2ex.com → 响应 301
    跳转 v2ex.com/
    suyingtao
        22
    suyingtao  
       2017-09-04 12:20:42 +08:00 via iPhone   ❤️ 1
    @zjp 这得看服务器的配置啊
    Showfom
        23
    Showfom  
       2017-09-04 12:43:32 +08:00 via iPhone
    严格来说都是不规范的
    doubleflower
        24
    doubleflower  
       2017-09-04 12:51:49 +08:00   ❤️ 1
    @zjp 你知道 HTTP 协议头吗?看看第一行,你说的这种情况不可能的,必需要有个 path,如果是根就是 / 而不是空白。

    @suyingtao 和服务器配置无关,HTTP 没办法不发送一个空路径。
    zjp
        25
    zjp  
       2017-09-04 13:50:54 +08:00 via Android
    @suyingtao 发现我搞混了,可能会做 301 跳转的是 path,请求根必须带"/"
    lonelinsky
        26
    lonelinsky  
       2017-09-04 15:00:05 +08:00
    @aleung 是 3986,不是 3968, 我锁搜出来怎么不对呢 =。=

    https://tools.ietf.org/html/rfc3986#page-16
    FrankFang128
        27
    FrankFang128  
       2017-09-04 15:01:12 +08:00
    看 RFC 的事情,非要发帖。。。
    mozutaba
        28
    mozutaba  
       2017-09-04 15:17:42 +08:00
    补齐了。。。
    zhicheng
        29
    zhicheng  
       2017-09-04 17:08:51 +08:00
    @weyou 第二种哪里不规范了?

    httpurl = "http://" hostport [ "/" hpath [ "?" search ]]

    hpath = hsegment *[ "/" hsegment ]

    hsegment = *[ uchar | ";" | ":" | "@" | "&" | "=" ]

    search = *[ uchar | ";" | ":" | "@" | "&" | "=" ]

    你发的 BNF,这个 '*' 是 匹配 0 个或多个的意思,hpath 是可以为空的。

    在 'www.example.com?' 和 'www.example.com/?' 是一样的,浏览器会自动补上 '/' 不然没办法构造请求。

    但对于其它路径不行,'www.example.com/hello' 和 'www.example.com/hello/' 是两个路径,有些 Web Server 会好心自动补上 '/' 或去掉 '/' 但有些不会。如果这两个路径表示的确实是同一个对象,服务器一般可以配置 URL rewrite 或把带 '/' 的 301 到不带 '/' 的路径上。
    weyou
        30
    weyou  
       2017-09-04 17:59:12 +08:00
    @zhicheng 首先应该参照 @aleung 说的 rfc3986, 我贴的 rfc1738 已经过时了。在 rfc3986 中这两种方式都是规范的。
    然后, 如果 hpath 是可以为空的, 那 BNF 应该是
    hpath = *[ "/" hsegment ]
    而不是
    hpath = hsegment *[ "/" hsegment ]
    这种方式代表至少有一个 hsegment. 后面的*代表 0 个或者多个[ "/" hsegment ]

    可以参照 rfc822 以及 rfc1738 中的说明:

    5. BNF for specific URL schemes

    This is a BNF-like description of the Uniform Resource Locator
    syntax, using the conventions of RFC822, except that "|" is used to
    designate alternatives, and brackets [] are used around optional or
    repeated elements. Briefly, literals are quoted with "", optional
    elements are enclosed in [brackets], and elements may be preceded
    with <n>* to designate n or more repetitions of the following
    element; n defaults to 0.
    weyou
        31
    weyou  
       2017-09-04 18:05:36 +08:00
    @zhicheng 好吧,hsegment 是可以为空的,所以 hpath 也可以为空,第二个确实可以的。
    aleung
        32
    aleung  
       2017-09-04 21:34:31 +08:00 via Android
    @weyou 按照 rfc1738, hpath 是可以为空,但是前面的斜杠也不能没有啊,否则就不能出现 search,确实是不合法。
    weyou
        33
    weyou  
       2017-09-04 22:23:10 +08:00 via Android
    @aleung 所以说在 rfc1738 下,第一种是非法的,而第二种是合法的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3166 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 12:23 · PVG 20:23 · LAX 05:23 · JFK 08:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.