How to rewrite SEO friendly url's like stackov

2019-01-23 21:00发布

问题:

If you go to a url like the following: http://stackoverflow.com/questions/9155602/ the address bar will be updated to http://stackoverflow.com/questions/9155602/redirect-existing-file-to-different-url-using-mod-rewrite. This is not done with JavaScript and not with a hard-refresh, my best guess is that it's done with mod_rewrite; however, how would it know the title of the article without server side processing with php?

I just updated my site to use SEO friendly url's, it used to be /shows.php?id=review-1 and now it's /review/1/super-baseball-2020. The text at the end doesn't actually really matter when it comes to my rewrite which is:

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

My current path of making sure Google doesn't hit me for duplicate content, and that bookmarks get forwarded properly is the following:

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 ....

That solution is very shortsighted and is thousands of lines to put into my .htaccess.

回答1:

how would it know the title of the article without server side processing with php?

mod_rewrite can only do so much. Plus, you'd have to update it too much. It's best to handle these requests with scripting. Create an .htaccess, similar to what you've done:

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

Then in your index.php, split the REQUEST_URI to parse out the /review/1/, look in the database for the title of the review with id of 1, pass it to your friendly URI (slug) function, and append it to the url, then redirect.



回答2:

I also have created an SEO-friendly URL solution for our show. The URL is naturally /raido/episode.php?SeriesId=1&EpisodeId=123, but I too wanted /radio/1-123-live.htm, so my .htaccess looks like this:

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

I then let the destination page handle it

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

This also allows you to continue to accept existing links without having to have 2 versions of the same code.



回答3:

for duplicate content, you should have a canonical link tag in the head. the canonical link tag will tell google that the current page has an alternate url for the same content as the canonical link, and the main url for this content is the canonical link. this is great for things like paginated content, searches, ect where the same page could have different urls.

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


回答4:

if i do a

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

i actually get a hard redirect:

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

often these setups contain a short .htaccess, forcing all requests to go through a front controller, or a main index.php file. this file checks the $_SERVER['PATH_INFO'] variable and decides what content to pull in and render.

this is a simple .htaccess example (actually just copied from a vanilla wordpress install):

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

in this example, with the hard redirect, they could have an "else" in the index.php, making lookups and redirecting correctly if no content can be found based on the last piece of PATH_INFO.



回答5:

You are going to either need to do this in the application itself by checking the URL against the absolute URL for the requested location, or by generating the mapping each time a new "page" is added.