如何重写SEO友好的URL像stackoverflow

时间:2012-02-06 22:34:59

标签: php .htaccess mod-rewrite redirect url-rewriting

如果您转到以下网址:http://stackoverflow.com/questions/9155602/,地址栏将更新为http://stackoverflow.com/questions/9155602/redirect-existing-file-to-different-url-using-mod-rewrite。这不是用JavaScript完成的,也不是用硬刷新做的,我最好的猜测是用mod_rewrite完成的;但是,如果没有使用php进行服务器端处理,它将如何知道文章的标题?

我刚刚更新了我的网站以使用SEO友好网址,它曾经是/shows.php?id=review-1,现在它是/review/1/super-baseball-2020。在我的重写时,最后的文字实际上并不重要,这是:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z0-9]+)/([0-9]+)/([a-z0-9-]+)?/?$ /shows.php?id=$1-$2 [L,NC]

我目前确保谷歌没有找到重复内容的路径,并且书签正确转发如下:

RewriteCond %{THE_REQUEST} ^GET\s/shows\.php\?
RewriteCond %{QUERY_STRING} (?:^|&)id=review-1(?:&|$) [NC]
RewriteRule ^ /review/1/super-baseball-2020/? [R=301,L,NC]
RewriteCond %{THE_REQUEST} ^GET\s/shows\.php\?
RewriteCond %{QUERY_STRING} (?:^|&)id=review-2(?:&|$) [NC]
RewriteRule ^ /review/2/aero-fighters-2/? [R=301,L,NC]
RewriteCond %{THE_REQUEST} ^GET\s/shows\.php\?
RewriteCond %{QUERY_STRING} (?:^|&)id=review-3(?:&|$) [NC]
RewriteRule ^ /review/3/aero-fighters-3/? [R=301,L,NC]
.... and so on ....

这个解决方案非常短视,可以输入数千行.htaccess。

5 个答案:

答案 0 :(得分:2)

  

如果没有服务器端,它如何知道文章的标题   用PHP处理?

mod_rewrite只能这么做。另外,你必须更新太多。最好用脚本来处理这些请求。创建.htaccess,类似于您所做的:

<IfModule mod_rewrite.c>
RewriteEngine On
#RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php [QSA,L]
</IfModule>

然后在index.php中,拆分REQUEST_URI以解析/review/1/,在数据库中查找id为1的评论标题,然后传递给它到友好的URI(slug)函数,并将其附加到url,然后重定向。

答案 1 :(得分:2)

我也为我们的节目创建了一个SEO友好的URL解决方案。该URL自然是/raido/episode.php?SeriesId=1&EpisodeId=123,但我也想要/radio/1-123-live.htm,所以我的.htaccess看起来像这样:

RewriteRule ^ \ d {1,3} - \ d {1,4}(。+)。html $ episode.php?Slug = $ 0

然后我让目标页面处理它

if ($Slug !== "") {
  $lIds = explode("-", $Slug);
  $SeriesId=$lId[0];
  $EpisodeId=$lIds[1];
}

这也允许您继续接受现有链接,而无需拥有相同代码的2个版本。

答案 2 :(得分:2)

对于重复内容,您应该在头部有一个规范的链接标记。规范链接标记将告诉谷歌当前页面具有与规范链接相同内容的备用URL,并且此内容的主URL是规范链接。这对于分页内容,搜索等内容非常有用,因为同一页面可能有不同的网址。

<link rel="canonical" href="http://www.somedomain.com/mainurl" />

答案 3 :(得分:2)

如果我做了

curl -I http://stackoverflow.com/questions/9155602/

我实际上得到了一个严格的重定向:

HTTP/1.1 301 Moved Permanently
Cache-Control: public, max-age=60
Content-Length: 0
Content-Type: text/html
Expires: Mon, 06 Feb 2012 22:43:27 GMT
Last-Modified: Mon, 06 Feb 2012 22:42:27 GMT
Location: /questions/9155602/redirect-existing-file-to-different-url-using-mod-rewrite
Vary: *
Date: Mon, 06 Feb 2012 22:42:27 GMT

这些设置通常包含一个简短的.htaccess,强制所有请求通过前端控制器或主index.php文件。此文件检查$ _SERVER ['PATH_INFO']变量并决定要引入和呈现的内容。

这是一个简单的.htaccess示例(实际上只是从一个vanilla wordpress安装中复制而来):

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

在这个例子中,使用硬重定向,它们可以在index.php中有一个“else”,如果根据最后一段PATH_INFO找不到内容,则可以正确查找和重定向。

答案 4 :(得分:0)

您需要在应用程序本身中执行此操作,方法是根据请求位置的绝对URL检查URL,或者每次添加新“页面”时按generating the mapping