hey all! i have an odd problem with URL routing. when i request a URL that doesn’t exist, e.g. http://localhost/foo, wordpress correctly returns a 404. however, if that URL is a prefix of a post or page name, it instead returns a 301 redirect to the post or page.
for example, if i have a post on 10/1/2010 named Food Post, it will return a 301 with Location: http://localhost/2010-10-01_food_post (my permalink structure). likewise, if i have a page named Food Page, it will return a 301 with Location: http://localhost/food_page.
you can see this in action on my live site, http://snarfed.org/ . e.g. http://snarfed.org/foo redirects to http://snarfed.org/2009-10-30_food_highlights .
turning off permalinks (ie switching to “default”) fixes it, for both posts and pages, but naturally i don’t really want to do that.
i see this on three different installations, all wordpress 3.0.1 and apache 2.2, two ubuntu lucid/mysql 5.1 and one freebsd 7.3/mysql 5.0. i’ve deactivated all plugins and removed everything from my .htaccess except the lines for wordpress below, verbatim, but no luck.
RewriteEngine On
RewriteBase /
RewriteRule ^wordpress/index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
thanks in advance…
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
This is normal, it is because redirect_canonical(), which makes sure you are always at a “canonical” URL (conforming to your permalink structure), executes redirect_guess_404_permalink() to make a best guess at a post when the URL is incomplete. If you want to prevent this, I think the best way is to hook into the redirect_canonical filter, and return false if it is a 404. Something like this:
add_filter('redirect_canonical', 'no_redirect_on_404');
function no_redirect_on_404($redirect_url)
{
if (is_404()) {
return false;
}
return $redirect_url;
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0