页面重定向中的无限循环



我们不断开发不同的页面供内部使用,有些页面可能会重定向到其他页面。假设公司规模越来越大,页面就会越来越多。有没有一种方法可以检测这些页面之间的重定向循环?

构建一个图,每个页面都有一个节点,如果页面a重定向到页面B,则有一条从节点a到节点B的定向边。

那么你的问题就是在有向图中找到一个循环的经典问题。这是使用Tarjan的强连通分量算法来解决的,其中每个大小>1表示这些页面之间的循环。

您可以在查询参数中传递重定向面包屑,在每次重定向时检查您重定向到的页面是否已经出现在面包屑中:

breadcrumbs = querystring["breadcrumbs"].split("-")
if not breadcrumbs.contains(targetpageid) then
redirect(targetpageurl + "?breadcrumbs=" + querystring["breadcrumbs"] + "," +  mypageid)

甚至可以调整以上内容,使第一个在面包屑中出现两次的页面终止重定向循环,这样每个页面只需要知道自己的页面id(而不需要知道其目标的页面id(。当然,如果重定向URL可能仅在查询参数上有所不同,那么您可能重定向的每个参数组合都需要不同的页面ID;在这种情况下,对URL进行散列(不包括breadcrumbs参数(并将该散列用作页面ID可能是有意义的。如果函数不会产生太多冲突,则可以使用相对较短的散列。

如果你担心用户在最后一页上看到丑陋的大面包屑字符串(一旦重定向停止(,你也可以让你的页面不再检测到重定向,然后在不使用面包屑参数的情况下重定向到它们自己。您可以将缺少breadcrumbs参数表示页面不得重定向,也可以将页面重定向到其自身,并将breadcrumps字符串设置为其自己的pageid。如果你使用上面提到的修改,让页面在面包屑中检测到自己两次时停止循环,这将起作用,用户只会看到一个页面id,即他们正在查看的页面的id。

显然,将breadcrumb信息放在查询字符串中允许最终用户覆盖行为,并有效地防止或允许重定向。如果您不想允许这样做,可以将面包屑信息保留在后端(数据库、redis等(,并在查询字符串中传递一个会话。每次重定向都会使用会话键来查找面包屑,系统的工作方式或多或少与上述相同。

您甚至可以通过在某个地方写日志或发送电子邮件,让系统在发生这种情况时通知管理员。如果您不想要循环,并且目标是在发现循环时将其删除,而不是简单地在运行时通过中断现有的循环来阻止无限重定向,那么这可能会很有帮助。

最新更新