将 404 重定向到类似的 url

Posted

技术标签:

【中文标题】将 404 重定向到类似的 url【英文标题】:redirect 404 to similar urls 【发布时间】:2012-02-15 00:28:36 【问题描述】:

我有一个网站,里面有故事。我可以在多个类别中拥有多种类型的故事,例如:

孩子们 浪漫 科幻 动作 惊悚片 任务

可以使用以下网址访问这些故事:

www.example.com/action/story-name-action/
www.example.com/romance/story-name-romance/

第一个参数 (action) 和第二个参数 (story-name-action) 使用规则使用 .htaccess 重定向。 这部分工作得很好。

最近,我从不同的站点获得了几十个 404,这就是我想做的,但我不知道如何:

如果有人输入,例如:/action/story-nme-ction,我想重定向到:action/story-name-action/

有没有一种有效的方法来实现这一点?

【问题讨论】:

静态文件有mod_speling。 "我从不同的站点获得了几十个 404" 这是什么意思?您的意思是网站已断开指向您网站的链接? 【参考方案1】:

天哪,天哪!

你的要求并不简单,需要你有一台功能强大的电脑,但结果简直太棒了。

以下是我的建议:

为了正确处理 404,您在 vhost 配置中有 ErrorDocument 重定向。我的看起来像这样:ErrorDocument 404 /404.php; 当有 404 时,Apache 将调用带有所有参数的 /404.php(哪个错误的 URL 等等,转储 $_SERVER 以查看此内容)。您必须测试 URL / 中是否只有两个表达式,即 http://mysite.com/(expr1)/(expr2)/ 如果没有,则执行经典 404。 如果是,则使用 mysql 搜索 SOUNDEX(在您的 404 Php 文件中)。请参阅查询示例here。 然后,在这种“特殊”404 案例中,像 google 一样提出建议,即:“您的意思是 /action/story-name-action/?如果是,请点击链接”。

这是一项艰巨的工作,但它既有趣又显示了您的技能。很少有网站这样做(实际上我只知道 google)。

这是我的法语表上的一个演示,可以让您大致了解它的工作原理:

mysql> SELECT * FROM job WHERE
SOUNDEX( description ) LIKE SOUNDEX('Machiniste cinéma');
+-------+--------------------+
| id    | description        |
+-------+--------------------+
| 14018 | Machiniste cinéma  |
+-------+--------------------+
1 row in set (0.06 sec)

mysql> SELECT * FROM job WHERE
SOUNDEX( description ) LIKE SOUNDEX('Mchiniste cinéma');
+-------+--------------------+
| id    | description        |
+-------+--------------------+
| 14018 | Machiniste cinéma  |
+-------+--------------------+
1 row in set (0.06 sec)

mysql> SELECT * FROM job WHERE
SOUNDEX( description ) LIKE SOUNDEX('Machnste cinema');
+-------+--------------------+
| id    | description        |
+-------+--------------------+
| 14018 | Machiniste cinéma  |
+-------+--------------------+
1 row in set (0.06 sec)

mysql> 

【讨论】:

Soundex 用于自然语言解析 - 它确实具有开箱即用 mysql 的优势,但是数字在 soundex 中具有非常特殊的意义,并且它不处理非字母数字(什么“@?/!”听起来像吗?) 你是对的。我刚刚提出了最接近 natalia 想要的唯一解决方案。而她想要的几乎是不可能做到的。 感谢Typex,没听说过,google上也没有有价值的链接。我确实同意,对于少数 % 的错误来说,这是一项繁重的工作。无论如何...您是否尝试在 MySQL 中进行类似SELECT * FROM table WHERE SOUNDEX( table.column ) LIKE SOUNDEX('story-nme-ction') 的查询?我用真实的演示编辑了我的问题 =) 如果你有Typex的链接我很感兴趣! 因为您查询WHERE SOUNDEX(description) LIKE SOUNDEX('Machnste cinema'),您应该将SOUNDEX(description) 存储在它自己的列中,例如descriptionex。然后你可以去WHERE descriptionex LIKE SOUNDEX('Machnste cinema')descriptionex 是可索引的,非常适合性能。【参考方案2】:

除非您非常确定用户真正想要导航到的 URL,否则使用重写/重定向到特定 URL 是一个非常糟糕的主意。

以您的示例为例,假设您要处理可能已删除两个字母的每种情况,在 URL 的最后部分有 17 个字符,即 17*16 = 272 个组合,而可能匹配多个 '带有一个正则表达式的 false' url,你仍然需要大量的重写规则。

更好的解决方案是,使用 PHP 实现 404 处理程序(因为您在 q 中包含该标签),生成(例如)前 10 个 URL 的列表,其路径与请求的路径之间的距离最短,以及默认链接和支持文本。 (有基于 mysql 的实现 - 尝试使用 Google 获取 URL)。 NB 处理程序仍应返回 404 状态 - NB html 内容必须超过最小长度才能抑制 MSIE 的“友好”错误消息。

【讨论】:

+1.. 我正要自己写。也许像 MySQL 级别的 SOUNDEX 这样的东西可以用来查找类似的 URL。或SELECT * FROM pages WHERE pageUrl SOUNDS LIKE userEnteredUrl.【参考方案3】:

如果您知道可能的正确 URL,您可以使用:

levenshtein($givenURL, $possibleURL)

PHP 文档中的示例,为简洁起见删除了 cmets:

$input = 'carrrot';

$words  = array('apple','pineapple','banana','orange',
                'radish','carrot','pea','bean','potato');

$shortest = -1;

foreach ($words as $word) 
    $lev = levenshtein($input, $word);
    if ($lev == 0) 
        $closest = $word;
        $shortest = 0;
        break;
    
    if ($lev <= $shortest || $shortest < 0) 
        $closest  = $word;
        $shortest = $lev;
    


echo $shortest == 0 ? "Exact match found: $closest\n" : "Did you mean: $closest?\n";

输出:

输入词:胡萝卜 你的意思是:胡萝卜?

当您认为人们可能遗漏了一个字母或添加了一个额外的字母时,这很好,但当人们真的不知道如何拼写一个单词并想出了一些有创意的东西时,它可能会失败!

如果您更喜欢soundex() 路由,请查看metaphone() 函数。

我喜欢将metaphone()levenshtein() similar_text()一起使用的想法,因为它会返回单词的语音表示,并且您仍然想看看它与您的原创。

例子:

metaphone('name') = NM
metaphone('naaaaaameeeeeeee') = NM
metaphone('naiym') = NM
metaphone('naiyem') = NYM

虽然很多拼写错误会返回相同的匹配项,但最后一个示例表明您仍然希望找到与 levenshtein() 之类的最接近的匹配项

为了提高效率,如果您使用不同的 404 文件,其中重写尝试匹配此模式并失败,而不是您在网站的其余部分使用,这真的不应该是一个巨大的开销。

如果您经常从同一个引荐来源网址获得相同的 404,(并且无法让他们更改链接),则可能值得为这种情况进行静态重写。

【讨论】:

【参考方案4】:

有几个解决方案:

确定错误 URL 的来源。这根本不应该发生,我无法想象为什么会发生。其他人是否从其他地方链接并且他们打错了(忽略复制和粘贴的存在)?您能看到这来自哪里(推荐人)并与他们联系吗? 在 URL 中添加一个 ID,例如 /action/123/story-name-action,您可以在其中根据 ID 而不是标题查找文章(奖励:增加了创建具有相同标题的同一类别的多个故事的可能性) 在标题上添加fuzzy search,使用soundex 之类的内容,然后将用户重定向到最合适的标题或显示带有类似标题的概览页面,例如@symcbean 建议。

不过我更喜欢 ID 那个。

【讨论】:

【参考方案5】:

我们为这样的 url 设置重定向到搜索页面 - 我们的搜索具有“建议”功能。

【讨论】:

【参考方案6】:

由于这些值(可能)是根据标题从 MySQL 中提取的,您可以在标题列上放置一个FULLTEXT 索引,并使用 MySQL 的 MATCH() 函数找到最相关的匹配项,并重定向用户到那个。

尽管这绝不是一个完美的解决方案 - 以任何真正的准确度执行此操作所需的情报类型正在危险地转向Turing test 领域。

【讨论】:

以上是关于将 404 重定向到类似的 url的主要内容,如果未能解决你的问题,请参考以下文章

删除 404 重定向上的所有 url 参数

如果 url 模式不匹配,Django 如何重定向到 404 页面

如果在 django 的 urls.py 中找不到,则将任何 url 重定向到 404.html

Spring Webflux 将所有 404 页面重定向到 index.html

Django 动态 url 重定向到 404

如何使用自定义 django 404 错误视图重定向?