Rewrite rule htaccess disturbing other rewrite rules

随声附和 提交于 2019-12-11 09:37:59

问题


I have a page on my website that is getting generated dynamically to list all outlets based on cityf parameter and below is rewrite rule to convert it into SEO friendly URL and it is working pretty well.

RewriteRule ^([^/.]+)/?$ /cityres?cityf=$1 [L]

I have a blog page on my website and .htaccess is as below to convert SEO Friendly URL (http://example.com/title-of-blog)

RewriteRule ^([^/.]+)/?$ /blogdetail?prmn=$1 [L]

Now the problem here i am facing that when someone visits blog page then the link http://example.com/title-of-blog instead of displaying blog detail on the page, displays my Error message that No outlets near title-of-blog.

I got the issue that Apache is not able to identify when to rewrite cityres page and when to rewrite blogdetail page.

Someone suggested that Make sure that each rule has a common prefix (e.g. /blog/page1 and /news/page2). but i did not get that.

Any suggestions here please?


EDIT:
Whole htaccess is as below
Options +FollowSymLinks
RewriteEngine On

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php
RewriteRule ^index\.php$ / [L,R=301]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index
RewriteRule ^index\.php$ / [L,R=301]

RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]

# remove .php from URL
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L] 

# remove .html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)\.html$ /$1 [L,R=301] 

ErrorDocument 404 /error-page
ErrorDocument 403 /error-page 

RewriteRule ^food-([^-]*)-([^-]*)\.html$ /pdetail?res_id=$1&location=$2 [L]
RewriteRule ^foodies-([^-]*)-([^-]*)$ /pdetail_new?res_id=$1&location=$2 [L]
RewriteRule ^([^/.]+)/([^/.]+)/([^/.]+)/?$ /pdetail_ne?location=$1&res_id=$2&name=$3 [L]

RewriteRule ^blog/([^/.]+)/?$ /blogdetail_fm?prmn=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !cityres
RewriteRule ^([^/.]+)/?$ /cityres?cityf=$1 [L]

回答1:


Both your rules match the exact same pattern. Therefore, the first rule will always match and the second rule does nothing.

Looking at the first rule:

RewriteRule ^([^/.]+)/?$ /blogdetail?prmn=$1 [L]

This matches http://example.com/title-of-blog as well as http://example.com/city-name

When you look at it, you can tell which needs to be handled by blogdetail and which needs to be handled by cityres, but the regex ([^/.]+) sees them both as exactly the same, and matches both. Your regex doesn't know the difference, so whatever the first rule is, both URL's will get matched by it.

Like you said, someone suggested using a prefix. That way, the regex knows which is which:

RewriteRule ^city/([^/.]+)/?$ /cityres?cityf=$1 [L]
RewriteRule ^blog/([^/.]+)/?$ /blogdetail?prmn=$1 [L]

ANd your URLs will look like:

http://example.com/city/city-name
http://example.com/blog/title-of-blog

If you're really hung up about not adding prefixes, you can remove the second prefix:

RewriteRule ^city/([^/.]+)/?$ /cityres?cityf=$1 [L]
RewriteRule ^([^/.]+)/?$ /blogdetail?prmn=$1 [L]

So that you have:

http://example.com/city/city-name
http://example.com/title-of-blog

EDIT:

Your 500 server error is caused by the rules looping. You need to add a condition so that they won't keep matching:

RewriteRule ^blog/([^/.]+)/?$ /blogdetail?prmn=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !cityres
RewriteRule ^([^/.]+)/?$ /cityres?cityf=$1 [L]


来源:https://stackoverflow.com/questions/28174865/rewrite-rule-htaccess-disturbing-other-rewrite-rules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!