为什么URI编码('#')锚导致404,以及如何在JS中处理它
Why URI-encoded ('#') anchors cause 404, and how to deal with it in JS?
prettyPhoto使用标签,但如果它们被编码(到%23),大多数浏览器都会出现404错误。这在前面已经讨论过:
您会得到一个404错误,因为#callback部分不是URL的一部分。这是浏览器使用的书签,而且从未发送向服务器发送请求。如果对哈希进行编码,它将成为改为文件名。
-
为什么散列仅仅因为是URI编码的就成为文件的一部分?这不是一只虫子吗?
-
我这么问是因为prettyPhoto使用了标签,也遇到了同样的问题。我想加一个"?"在散列成为最优雅的解决方案之前,我只是有点不知所措如何在现有代码中进行:
函数getHashtag(){url=location.href;hashtag=url.indexOf('#gallery')==-1) ?decodeURI(url.substring(url.indexOf('#gallery')+1,url.length)):false;返回标签;}函数setHashtag(){if(typeoftheRel=='undefined')返回;location.hash=rel+'/'+rel_index+'/';}函数clearHashtag(){if(location.href.indexOf('#gallery')==-1) location.hash=";}
-
还有其他建议吗?我会考虑调整我的404页面,但这似乎更像是处理问题,而不是阻止它
谢谢!
编辑:由于prettphoto处理这些哈希的方式显然没有错,我最终将这些规则添加到了我的apache服务器中:
RewriteRule ^(.*).shtml(%23|#)$ /$1.shtml [R=301,NE,L]
RewriteRule ^(.*).shtml([^g]+)gallery(.+)$ /$1.shtml#gallery$3 [R=301,NE,L]
他们成功地处理了%23引起问题的案例。
- 为什么散列仅仅因为是URI编码的就成为文件的一部分?这不是一只虫子吗
如果您将浏览器指向http://example.com/index.html#title
,则浏览器会将其解释为从服务器example.com
请求文件index.html
。请求完成后,浏览器会在文档中查找名称为"title"(即<a name="title">My title</a>
)的锚点元素。
如果指向http://example.com/index.html%23title
,则浏览器会从example.com
请求文件index.html%23title
,而服务器上可能不存在该文件,从而得到404。看到区别了吗?
而且它不是虫子。它是互联网标准的一部分,上次更新是在1998年。参见RFC 2396。报价:
字符"#"被排除在外,因为它用于从URI引用中的片段标识符分隔URI(第4节)。
至于2和3,示例代码中没有足够的上下文来说明您要做什么。您是如何调用代码的?你想用不起作用的prettypoto做什么?您是否试图从用户点击或其他javascript事件重定向到特定的照片或图库?当有人访问某个特定页面时,你是否试图打开图库?
我在twitter/oauth上检查了链接的问题,但我不知道这与您提供的代码有什么关系。我也开始研究prettypoto,但我也不明白你的代码与之有什么关系。
您可能需要的不是更改404页面,而是一个代码内处理程序或服务器重写规则,该规则接受包含%23
的未找到请求,并将用户重定向到解码后的url。这可能有一些缺点,但如果你接受来自其他无法控制的来源的传入请求,那就相当不错了。您的服务器环境是什么?(语言、服务器技术、机器所有者等)
我很乐意为您提供解决方案或解决方案来更新我的答案。
回答#1)
它将成为URL的一部分,因为它不再是浏览器/服务器等知道如何解析的令牌。
我的意思是,"?"在URL中扮演着重要的角色——服务器知道将之前的内容与之后的内容区分开来。浏览器不需要关心URI中哪些是动态的,哪些不是动态的——这一切都很重要(尽管JavaScript将位置对象中的值分开)。
浏览器不会向服务器发送"#……",因为标签对浏览器有特殊的含义。
但是,如果您在JavaScript中转义该散列,浏览器将毫不犹豫地将转义字符串作为文本值发送到服务器。
为什么不呢?如果你的搜索查询合法地需要一个散列字符(你向脸书墙发出POST请求,并且你提交了一个电话号码),那么你就完蛋了。或者你正在411.com或其他网站上进行基于GET的搜索,但他们并没有真正仔细考虑他们的应用程序。
问题是,如果转义值发生在实际路径中,服务器不会理解它将与url分开保存。
它必须接受转义字符,否则在文件名/路径/查询/值中有效的空格(%20)和其他日常字符会带来问题。
因此,如果你正在寻找:
//mysite.gov.on.ca/path/to/file.extension%23action%3Dfullscreen
的确,你肯定会404。
我敢肯定,你可以做一些事情。第一个是在Apache中,或者无论你从哪里提供服务,你都可以编写一个RegEx,它匹配第一个"%23"之前的任何url,假设事先没有"?"。
不那么令人心碎的实现可能需要弄清楚是否有办法摆脱插件友好的"#"。
例如,谷歌使用"hash-bang"策略("#!"),要求以这种方式提交URL,以知道是否进行编码。
其他选项可能是使用url.indexOf("#");
检查"#"字符,并在哈希处拆分URL,然后提交有效部分。
实际上,这一切都取决于你试图实现的目标——我可以指出为什么这是一个问题,但如何最好地使它成为一个非问题取决于你正在努力做什么,如何努力做到这一点,以及在你工作的环境中允许做什么。
- Node.JS处理重复的可传递依赖关系
- React.js处理第三方库安装
- 如何发布单选和复选框选择?表单由php和js处理
- 使用Backbone.js处理浏览器历史记录
- Ember.js处理View事件后转换到路由
- 节点.js:如何使用验证器.js处理多个验证
- 使用 Angular.js 处理基于 OAuth 令牌的身份验证
- 反应.js - 处理哑儿童状态的模式
- JS处理延迟后输入仅一次
- 使用 Handlebars.js 处理 executeSql 语句的结果
- Node JS - 处理多个查询(promise,bluebird)
- 节点.js处理异步
- 保存用caman.js处理过的图像
- kue node.js处理作业行为
- 如何使用angular js处理jsonarray响应?我得到了
- 什么'这是用express.js处理mongose连接的正确方法
- Node.js处理http请求的响应
- angular.js处理动态获取的数据
- 使用js处理iframe时出错
- Angular JS处理控制器事件