为什么URI编码('#')锚点会导致404,以及如何在JS中处理它?

Dre*_*rew 8 javascript hash webkit hashtag

prettyPhoto使用主题标签,但如果它们被编码(到%23),大多数浏览器都会出现404错误.这之前已经讨论:

您收到404错误,因为#callback部分不是URL的一部分.它是浏览器使用的书签,它从未在请求​​中发送到服务器.如果对哈希进行编码,则它将成为文件名的一部分.

  1. 为什么哈希会成为文件的一部分,因为它是由URI编码的?这不是一个bug吗?

  2. 我问,因为prettyPhoto使用主题标签并遇到同样的问题.我想加一个'?' 在哈希是最优雅的解决方案之前,我只是有点不知道如何在现有代码中做到这一点:

    function getHashtag(){
    url=location.href;
    hashtag=url.indexOf('#gallery')!==-1)?decodeURI(url.substring(url.indexOf('#gallery')+1,url.length)):false;
    return hashtag;
    }
    function setHashtag(){
    if(typeof theRel=='undefined')return; location.hash=theRel+'/'+rel_index+'/';
    }
    function clearHashtag(){
    if(location.href.indexOf('#gallery')!==-1)location.hash="";
    }
  3. 还有其他建议吗?我会考虑调整我的404页面,但这似乎更像是处理问题而不是阻止它.

谢谢!

编辑: 由于相机处理这些哈希的方式显然没有任何问题,我最终将这些规则添加到我的apache服务器:

RewriteRule ^(.*).shtml(%23|#)$ /$1.shtml [R=301,NE,L]
RewriteRule ^(.*).shtml([^g]+)gallery(.+)$ /$1.shtml#gallery$3 [R=301,NE,L]
Run Code Online (Sandbox Code Playgroud)

他们成功处理了%23引发问题的案例.

Pat*_*k M 10

  1. 为什么哈希会成为文件的一部分,因为它是由URI编码的?这不是一个bug吗?

如果您将浏览器指向http://example.com/index.html#title,浏览器会将其解释为index.html从服务器请求该文件example.com.请求完成后,浏览器会在文档中查找名为"title"(即<a name="title">My title</a>)的锚元素.

如果改为指向http://example.com/index.html%23title,浏览器发出的文件的请求index.html%23titleexample.com,这可能并不存在于服务器上,给你404看到区别?

这不是一个错误.它是1998年最新更新的互联网标准的一部分.请参阅RFC 2396.引用:

排除字符"#",因为它用于从URI引用中的片段标识符分隔URI(第4节).

对于2和3,您的示例代码中没有足够的上下文来告诉您要执行的操作.你怎么称呼你的代码?你想用Prettyphoto做什么不工作?您是否尝试从用户点击或其他javascript活动重定向到特定照片或图库?当有人访问特定页面时,您是否尝试打开图库?

我用twitter/oauth检查了链接的问题,但是我没看到它与你提供的代码有什么联系.我也开始在prettyphoto上戳,但我也看不出你的代码与之相关.

您可能需要的是一个代码内处理程序或服务器重写规则,它不需要更改您的404页面,而是将未找到的请求带入%23其中,并将用户重定向到已解码的URL.这可能有一些缺点,但如果您从其他来源接收无法控制的传入请求,那将会相当优雅.你的服务器环境是什么?(语言,服务器技术,拥有该机器等)

我很乐意通过解决方案或为您解决问题来更新我的答案.