使用JS将URL #fragment转换为丢失到301重定向之前?

时间:2015-06-10 20:14:16

标签: javascript redirect

这里真的很麻烦。我们的旧网站上有一个图库滑块,它使用URL #fragments在正确的项目中定位jQuery滑块。

例如,/work/interactive#777将您带到/ work / interactive页面 - 它在滑块中一次显示一个项目 - 然后设置滑块以使用777的ID进行投影

我们准备推出一个包含相同项目的新网站,但这些项目现在是完全合格且独立的网页,因此新网站上的上一个项目位于/work/777

最大的问题是我们需要为以下内容提供301重定向:

发件人:/work/interactive收件人:/our-work

如果有哈希,以某种方式在丢失之前捕获它,所以在重定向之后我们可以使用Javascript来处理项目的#ID。

我似乎只能做一个或另一个:301重定向根页面没有#fragments(这阻止我检查#fragment),或使用全局javascript来检查URL和#片段并使用window.location重定向到新网站上的单个项目页面(这会阻止我进行任何301重定向)。

有关如何保留#fragment的任何想法?当且仅当请求URL没有#fragment时,有没有办法有条件地执行301?

2 个答案:

答案 0 :(得分:2)

这是不可能的,因为浏览器没有将片段部分传递给服务器,同时只有服务器可以进行301重定向。

如果您需要保留旧的超链接,我建议您保留此特定案例的当前网站网址。

答案 1 :(得分:1)

这是可能的(现在)。但是,可能仍然存在一些不符合该规范的旧版浏览器:https://tools.ietf.org/html/rfc7231#section-7.1.2

解决方案:

首先 ,设置服务器301重定向,以便将对/work/interactive的所有请求发送到/our-work

第二 ,将以下JavaScript代码放在HTML页面顶部/our-work处。该代码将使用window.location.hash查看该片段,如果不为空,则会根据找到的片段重定向到/our-work/xxx。我使用的是replace函数而不是assign,这样浏览器的历史记录就不会记住带有片段的初始请求。由于window.location.hash将以#开头,因此我使用substring(1)删除了第一个字符。

<script>
  if (window.location.hash !== "") {
    window.location.replace(window.location.pathname + "/" + window.location.hash.substring(1));
  }
</script>

即使/our-work是有效的页面(例如,所有产品的列表页面)也可以使用。没有片段的任何请求产品列表页面的人都不会被重定向。产品列表页还将使搜索引擎能够在其新位置快速找到内容并为其重新编制索引。

预期行为:

/work/interactive#777的请求应首先由服务器(例如301)重定向,兼容的浏览器将首先请求/our-work#777。服务器将使用HTML / JS代码块(最好还包含其他后备HTML内容)进行回复。根据性能,用户可能会在执行JavaScript之前短暂地看到其他一些HTML内容。然后,浏览器将被重定向到/our-work/777并加载了预期的HTML页面。

或者,对/work/interactive的请求(即无片段)应由服务器重定向,然后浏览器将请求/our-work。服务器将回复HTML / JS代码块,最好还会回复其他后备HTML内容。由于没有片段,因此HTML / JS代码块不应执行任何操作。用户只会看到后备HTML内容(例如产品列表页面)。

假设:

  • 每个可能的片段在/our-work/xxxx 上都有一个有效的页面。对于上面的代码示例,无论片段包含什么内容,我们都会重定向。如果您只想重定向某些片段,则可以使用更具体的测试,例如:if (/^[#]([0-9]{3}$)/.test(window.location.hash)) { ... }。这只会重定向严格的3位数数字片段。或根据情况调整正则表达式。
  • 您的新页面不包含保证其自身片段的内容。如果您的新页面应该处理自己的片段(例如/our-work#intro/our-work#portfolio等),那么您将需要使用更具体的测试来仅选择性地重定向(请参见先前的假设< / em>)。
  • 这些片段不编码其他信息。如果片段包含更复杂的数据,则可以在重定向之前进行进一步的处理。例如,您可以解析以下请求:/work/interactive#777-description/work/interactive#777-author,然后重定向到/our-work/777#description/our-work/777#author

进一步的解释:

如果客户端(例如浏览器)希望加载http://www.example.com/old.html#fragment,则通常会首先从位于/old.html的服务器发出对www.example.com的请求。如果该资源在该位置可用,则一旦收到,客户端就会寻找该片段,并在找到该片段时进行调整(例如,滚动视口)。

但是,当服务器通过发送301302等HTTP响应和新的Location(例如/new.html)指示资源已移动时, ,则客户端应首先向/new.html发出新请求,然后在收到请求后,仍应处理该片段并进行调整。这意味着重定向后,浏览器地址栏应显示http://www.example.com/new.html#fragment

从历史上看,并非所有浏览器在重定向后都正确保留了该片段。

还要注意,根据规范,浏览器应优先考虑HTTP响应Location中指定的任何片段(例如Location: /new.html#newfragment)。而且,如果Location中未指定任何片段,则它应保留最初请求的任何片段。