URL 规范中,问号前面是否要添加斜杠? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Reign
V2EX    程序员

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

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

    一个动态的网址,比如: https://www.v2ex.com?page=2 以及 ?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
    如果是根的话需要加的吧
    0ZXYDDu796nVCFxq
        3
    0ZXYDDu796nVCFxq  
       2017-09-04 08:59:48 +08:00 via iPhone
    第一种不合法
    yemoluo
        4
    yemoluo  
       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 以及 ?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  
    PRO
       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  
    PRO
       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     Solana     2871 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 00:27 PVG 08:27 LAX 16:27 JFK 19:27
    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