8

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

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

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

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

    函数getHashtag(){
    网址=位置.href;
    hashtag=url.indexOf('#gallery')!==-1)?decodeURI(url.substring(url.indexOf('#gallery')+1,url.length)):false;
    返回标签;
    }
    函数 setHashtag(){
    if(typeof theRel=='undefined')return; location.hash=theRel+'/'+rel_index+'/';
    }
    函数 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]

他们成功处理了 %23 引起问题的情况。

4

2 回答 2

10
  1. 为什么哈希会因为它是 URI 编码而成为文件的一部分?这不是一个错误吗?

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

如果您改为指向,则浏览器向来自http://example.com/index.html%23title的文件发出请求,该文件可能在服务器上不存在,给您一个 404。看到区别了吗?index.html%23titleexample.com

这不是一个错误。它是1998 年最后一次更新的 Internet 标准的一部分。请参阅RFC 2396。报价:

字符“#”被排除在外,因为它用于将 URI 与 URI 引用中的片段标识符分隔(第 4 节)。

至于 2 和 3,您的示例代码中没有足够的上下文来说明您要做什么。你如何调用你的代码?你想用不工作的漂亮照片做什么?您是否尝试从用户点击或其他 javascript 事件重定向到特定照片或画廊?当有人访问特定页面时,您是否尝试打开图库?

我用 twitter/oauth 检查了链接的问题,但我看不出它与您提供的代码有何联系。我也开始研究漂亮的照片,但我也看不出你的代码与它有什么关系。

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

我很乐意为您提供解决方案或解决方法来更新我的答案。

于 2012-07-20T23:47:48.227 回答
2

回答#1)

它将成为 URL 的一部分,因为它不再是浏览器/服务器/等知道如何解析的令牌。

我的意思是那个“?” 在 URL 中扮演着重要的角色——服务器知道区分之前和之后的内容。浏览器不需要关心 URI 中什么是动态的或不是动态的——这都很重要(尽管 JavaScript 将位置对象中的值分开)。

浏览器不会向服务器发送“#......”,因为标签对浏览器具有特殊的含义。

但是,如果您在 JavaScript 中转义该哈希,浏览器会毫不犹豫地将转义的字符串作为文字值发送到服务器。

为什么不呢?如果您的搜索查询合法地需要一个哈希字符(您向 facebook 墙发出 POST 请求,并且您正在提交一个电话号码),那么您就完蛋了。或者您正在 411.com 或其他任何地方对某个号码进行基于 GET 的搜索,但他们并没有真正考虑过他们的申请。

问题是服务器不会理解转义值将与 url 分开保存,如果它发生在实际路径中。

它必须接受转义字符,否则在文件名/路径/查询/值中有效的空格 (%20) 和其他日常字符会造成问题。

因此,如果您正在寻找:

//mysite.gov.on.ca/path/to/file.extension%23action%3Dfullscreen

真的,你肯定会 404。

我敢肯定,你可以做一些事情。第一个将在 Apache 中,或者您所提供的任何服务,您可以编写一个正则表达式,它与第一个“%23”之前的任何 url 匹配,假设没有“?” 预先。

更少的灵魂撕裂实现可能涉及弄清楚是否有办法逃避插件友好的“#”。

例如,Google 使用“hash-bang”策略(“#!”)要求以这种方式提交 URL,以了解是否进行编码。

其他选项可能是检查“#”字符,使用url.indexOf("#");并在散列处拆分 URL,并提交有效部分。

这实际上都归结为您要完成的工作-我可以指出为什么这是一个问题,但是如何最好地使其成为非问题取决于您要做什么,如何尝试去做,以及在你工作的环境中允许做什么。

于 2012-07-21T00:04:54.730 回答