为什么URL的哈希部分在服务器端不可用?

49
4个回答

69

不,这只能在浏览器中使用,所以您需要使用Javascript来处理它。服务器无法读取它。

解释:
基本上,页面URL的哈希组件(#符号后面的部分)仅由浏览器处理 - 浏览器从不将其传递给服务器。遗憾的是,这是HTML标准的一部分,无论您是否使用IE或任何其他浏览器(以及PHP或任何其他服务器端技术),都是相同的。

这是维基百科对此的解释:

片段标识符与URI的其余部分功能不同:即其处理是完全由客户端完成,服务器不参与。当代理(例如Web浏览器)从Web服务器请求资源时,代理将URI发送到服务器,但不发送片段。相反,代理等待服务器发送资源,然后根据片段值处理资源。在最常见的情况下,代理将Web页面滚动到具有属性字符串等于片段值的锚元素。其他客户端行为也是可能的。


1
实际上,您可以使用PHP将哈希值urlencode('#')转换为“%23”,然后再次使用urldecode('%23')转换为“#”,以便将其传输到服务器。这不需要JavaScript,但需要PHP。如果您也不想使用PHP,可以手动在HTML代码中编写“%23”;-) - user1322720
3
不 @what,那不可靠。如果哈希标记在查询字符串后面,%23 将会被视为值的一部分,例如 ?foo=bar%23what,服务器会将其解释为 $foo = 'bar#what'。请注意,此时哈希标记不会生效。 - Oliver Williams
@OliverWilliams,更好的方法是使用查询参数。 - sktguha
在长时间搜索并试图理解为什么PHP无法读取用户输入的完整URL或链接中点击的链接后,我终于推断出了这个浏览器行为。如此令人沮丧的是,这在网络上没有更好的记录。这是少数正确的答案之一。这意味着PHP无法重定向或处理包含锚点名称的传入URL,多么糟糕的设计! - David Spector
很棒的答案!我一直在尝试找出为什么URL中后面的部分没有被发送到服务器。 - Binita Bharati

10

https://www.rfc-editor.org/rfc/rfc2396#section-4

当使用URI引用执行检索操作时,可选的片段标识符与URI由井号(“#”)字符分隔,包含在成功完成检索操作后由用户代理解释的附加引用信息。因此,它不是URI的一部分,但通常与URI一起使用。

总之,#MOREURL不会被发送到服务器?只能使用jQuery/AJAX/Javascript方法。 - CRISHK Corporation
jQuery和AJAX与此无关。它们只能通过Javascript或可能是其他客户端脚本语言访问,而不是服务器端。 - meder omuraliev
1
@user439866:哈希表就像电话系统中的分机号码一样。它是“接收方”的。你拨打电话号码,然后拨打分机号码——但分机号码实际上并不是电话号码的一部分(除非是某种直拨系统)——分机号码是一个“额外”的部分,由接收电话系统单独处理。我其实对电话系统的工作原理不太了解,所以这个比喻可能不正确。 - Cristian Sanchez

8
我想进一步解释为什么片段不会被发送到服务器,因为这是有意的和期望的行为。让我们看整个URL字符串。 /path/to/element?query=string&for=server#?optional=fragment&for=browser <----- URI ----> <---- QUERY STRING ---> <----- FRAGMENT STRING ------> URI唯一地指定从服务器获取的资源。 查询定义服务器对资源执行的操作。 片段控制浏览器(应用程序)的行为。片段应该用于存储应用程序状态,以便用户可以将链接发送给另一个用户以获得相同的应用程序状态。
片段是URL中唯一免费透明实现单页Web应用程序(例如可以在手机上离线运行)的部分。因此,它不应该被发送到服务器。

它可能会工作,但这并不意味着它完全按照预期工作。如果一个URL可以用锚点名称编写,那么它应该是URL的正式部分,并随请求一起发送到服务器。因为从未接收到锚点名称,所以PHP脚本无法重定向包含锚点名称的URL。 - David Spector
是的,这个标准唯一令人遗憾的地方就是只有一个真正有效的用例,那就是将文档的某个部分重定向到另一页。如果您使用哈希值跳转到该部分,则需要使用js进行重定向。 - Tofandel

0

哈希组件不会传递到服务器,但在客户端广泛使用。特别是在单页应用程序中,哈希后面的文本用于表示应用程序的状态作为不同路由。因此,发生的情况是:在向服务器发出初始请求并提供“主页”页面以及包括客户端路由逻辑(如路由器)的其他js文件之后,每当用户通过单击锚标记在页面上导航到任何位置时,仅更改跟随哈希组件的URL部分。这可以防止向服务器发送GET请求,并响应此“onhashchange”事件,可以根据确切的路由更新单页应用程序的内容。


除了客户端处理之外,如果服务器需要重定向或记录它,应该向服务器发送完整的URL。 - David Spector

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接