Difficulty Rewriting URL using .htaccess - .htaccess

I've seen several answers but none of them have worked for me.
How do I rewrite the below using my .htaccess? mod_rewrite is on in my file.
http://example.com/local/vendor/index.php?handle=Company
to be:
http://example.com/local/vendor/Company

How do I rewrite the below...
There's possibly a more fundamental problem here. You don't rewrite it that way round in .htaccess. You rewrite from the "friend" URL back to the actual URL/filesystem path. So, it's the other way round, you rewrite from:
http://example.com/local/vendor/Company
to the actual URL your application is expecting:
http://example.com/local/vendor/index.php?handle=Company
For Example:
RewriteEngine On
RewriteRule ^(local/vendor)/(Company)$ /$1/index.php?handle=$2 [L]
$1 and $2 are backreferences to the captured groups in the RewriteRule pattern.
The above matches just the specific URL you stated, ie. /local/vendor/Company. I suspect that "Company" is intended to be a placeholder? In which case you need to make this more general. For example:
RewriteRule ^(local/vendor)/(\w+)$ /$1/index.php?handle=$2 [L]
\w is a shorthand character class for word characters. This excludes the dot (ie. .) so avoids a rewrite loop when rewriting to index.php.
UPDATE: The above assumes your .htaccess file is located in the document root, ie. example.com/.htaccess. However, if the .htaccess file is located in the /local subdirectory (ie. example.com/local/.htaccess) - as you appear to suggest in comments - then you will need to adjust the above directives to remove local/ from the RewriteRule pattern and remove the slash prefix from the substitution. For example:
RewriteRule ^(vendor)/(\w+)$ $1/index.php?handle=$2 [L]

Related

Mirror a file in htaccess

I'm trying to work on making a new site and I want to be able to mirror a site. Below is an example:
User visits: https://example.com/items/{some child folder}
User sees this file mirrored: https://example.com/items/listing.php
I want user to be able to see that file, but, when doing so, it don't want it to redirect. Any ideas?
UPDATE
I found a solution to the above problem. However, I need another question fixed. How would I stop the file listing.php in the /products folder from following the redirect?
RewriteEngine On
RewriteRule ^products/(.*) index.php?name=$1 [NC,L]
How would I stop the file listing.php in the /products folder from following the redirect?
RewriteRule ^products/(.*) index.php?name=$1 [NC,L]
Be more specific in the regex. If your products don't contain dots in the URL-path then exclude dots in the regex. For example:
RewriteRule ^products/([^./]+)$ index.php?name=$1 [L]
The above assumes your product URLs are of the form /products/<something>. Where <something> cannot consist of dots or slashes (so naturally excludes listing.php) and must consist of "something", ie. not empty.
Unless you specifically need the NC flag then this potentially opens you up to duplicate content.
If you want to be explicit then include a condition (RewriteCond directive):
RewriteCond %{REQUEST_URI} !^/products/listing\.php$
RewriteRule ^products/([^/]+)$ index.php?name=$1 [L]
The REQUEST_URI server variable contains the root-relative URL-path, starting with a slash. The ! prefix on the CondPattern negates the regex.
Or, use a negative lookahead in the RewriteRule pattern, without using a condition. For example:
RewriteRule ^products/(?!listing\.php)([^/]+)$ index.php?name=$1 [L]
Reference:
https://httpd.apache.org/docs/current/rewrite/intro.html
https://httpd.apache.org/docs/current/mod/mod_rewrite.html

rewrite urls , not all urls works

I have blog and I want to rewrite the link
site.com/blog -> for the blog index blog_posts.php
site.com/blog/{post-slug} -> for the single_post.php?post-slug={post-slug}
site.com/blog/topic/{topic} -> for the filtered_posts.php?topic={topic}
my problem is when I access to a post or a topic its access to site.com/blog blog_posts.php
I think because when access to blog_posts.php and write after it any think like kbjsflgjdouihaiufhslkdf access to blog_posts.php
my try
RewriteRule ^blog/([0-9a-zA-Zأ-ي-]+)/ single_post.php?post-slug=$1 [NC,L]
RewriteRule ^blog/ blog_posts.php [NC,L]
RewriteRule ^blog/topic/([0-9a-zA-Zأ-ي-]+)/ filtered_posts.php?topic=$1 [NC,L]
and if there are any thing that tech all about the .htaccess please gimme a link
RewriteRule ^blog/([0-9a-zA-Zأ-ي-]+)/ single_post.php?post-slug=$1 [NC,L]
RewriteRule ^blog/ blog_posts.php [NC,L]
RewriteRule ^blog/topic/([0-9a-zA-Zأ-ي-]+)/ filtered_posts.php?topic=$1 [NC,L]
You need to change the order of the directives and/or make the regex more specific. Order is important - the most specific regex need to be first.
For instance, your first rule ^blog/([0-9a-zA-Zأ-ي-]+)/ will naturally match any URL of the form /blog/topic/<something>, so the request is rewritten to single_post.php and the 3rd rule is never processed.
And your 2nd rule (^blog/), matches anything else that simply starts /blog, so again, the 3rd rule would never be processed.
Your example URLs, eg /blog/{post-slug} do not include a slash suffix, however, the directives you have written look as if you are trying to match one? Although you are not using any end-of-string anchor on the regex, so you are probably matching too much. For instance, the regex ^blog/([0-9a-zA-Zأ-ي-]+)/ will match a URL of the form /blog/{post-slug}/1234/something/etc which is probably not the intention (if it is the intention then it's still a fault as you potentially have a duplicate content issue).
I'm assuming your URLs are as per your example - no trailing slash.
I also queried (in comments) whether /blog a physical directory on the filesystem? If it is then your first example URL, ie. /blog is not canonical since mod_dir will implicitly trigger a 301 redirect to append the trailing slash. I'm assuming this is a physical directory and the canonical URL is actually /blog/, not /blog.
Try the following instead:
RewriteRule ^blog/topic/([0-9a-zA-Zأ-ي-]+)$ filtered_posts.php?topic=$1 [L]
RewriteRule ^blog/([0-9a-zA-Zأ-ي-]+)$ single_post.php?post-slug=$1 [L]
RewriteRule ^blog/$ blog_posts.php [L]
I also remove the NC (nocase) flag. You are already checking for both lowercase and uppercase letters in the regex, but if you are also allowing uppercase letters in other parts of the URL then you potentially have a duplicate content (non-canonical) URL issue that would need to be resolved.
Reference:
https://httpd.apache.org/docs/current/rewrite/intro.html
https://httpd.apache.org/docs/current/mod/mod_rewrite.html

Redirection rule doesn't work in my .htaccess

I broke my head trying to find where the issue is:
I have the following redirection rule:
RewriteRule ^/productname(.*) https://website.com/category [R=301,NC,L]
but it doesn't work and I can't get why. Because this rule:
Redirect 301 ^/productname(.*) https://website.com/category/subcategory/productname
works fine.
Would appreciate any help
RewriteRule ^/productname(.*) https://website.com/category [R=301,NC,L]
That won't work in per-directory .htaccess files because the URL-path matched by the RewriteRule pattern is less the directory-prefix (the filesystem path of where the .htaccess file resides). The directory-prefix always ends in a slash, so the URL-path that is matched by the RewriteRule pattern never starts with a slash.
From the Apache docs for the RewriteRule directive:
In per-directory context (Directory and .htaccess), the Pattern is matched against only a partial path, for example a request of "/app1/index.html" may result in comparison against "app1/index.html" or "index.html" depending on where the RewriteRule is defined.
The directory path where the rule is defined is stripped from the currently mapped filesystem path before comparison (up to and including a trailing slash). The net result of this per-directory prefix stripping is that rules in this context only match against the portion of the currently mapped filesystem path "below" where the rule is defined.
So, you would need to do remove the slash prefix, for example:
RewriteRule ^productname https://website.com/category [R=301,NC,L]
The trailing (.*) on the RewriteRule pattern is superfluous in this example.
Redirect 301 ^/productname(.*) https://website.com/category/subcategory/productname
This rule wouldn't "work fine". I think you mean RedirectMatch.
Note that RewriteRule and Redirect (and RedirectMatch) belong to different modules. mod_rewrite and mod_alias - you should avoid mixing redirects from both modules as you can get unexpected conflicts.

.htaccess : redirect permanent and stop new rules

I have that rule that works well
RedirectMatch 301 ^/(.*?)-/(.*)$ /$1/$2
It redirects for instance
http://example.com/category-/list/town/id/id2/country ->
http://example.com/category/list/town/id/id2/country
Problem is, later .htaccess adds some extra query parameters.
My goal is: when this rule is matches, then do not apply other .htaccess rules
I tried with:
RewriteRule ^/(.*?)-/(.*)$ /$1/$2 [R=301,L]
and rule is not applied at all !
As #hjpotter92 mentioned in the comments, the pattern is without the leading slash in .htaccess files. See Apache mod_rewrite Technical Details
In per-directory context (i.e., within .htaccess files and Directory blocks), these rules are being applied after a URL has already been translated to a filename. Because of this, the URL-path that mod_rewrite initially compares RewriteRule directives against is the full filesystem path to the translated filename with the current directories path (including a trailing slash) removed from the front.
To illustrate: If rules are in /var/www/foo/.htaccess and a request for /foo/bar/baz is being processed, an expression like ^bar/baz$ would match.
RewriteRule has a similar note in the section "Per-directory Rewrites".
So your rule should look like
RewriteRule ^(.*?)-/(.*)$ /$1/$2 [R,L]
If you have this RewriteRule, you don't need the RedirectMatch anymore.

mod_rewrite rules not working as expected

I am using the following code
RewriteEngine on
RewriteRule ^/(certain|folders|on|server) - [NC,L]
RewriteRule (.*) http://newserver/blog$1 [L,NS]
I would expect it to ignore my list of folders, and redirect to everything else. Instead, it seems to always be redirecting to "newserver". Changing the "-" to a URL in the first statement does work, but I don't actually want those folders directed anywhere.
Why does my statement not work as expected?
Also, I have noticed that for all the folders not listed, I have "newserver/", while the ones I listed are just "newserver" (no uri)
You need to remove the leading slash in your rule. Rewrite rules in an htaccess file are given a URI to match against with the leading slash stripped off. Change your first rule by adding a ? after the slash:
RewriteRule ^/?(certain|folders|on|server) - [NC,L]
Or you can change it into a condition:
RewriteCond %{REQUEST_URI} !^/(certain|folders|on|server)
that will be applied to the rule that follows it.
Turns out my rules do work as expected. I was previously trying using these rules in apache.conf. Moving it to the sites "VirtualDirectory" tag seemed to do the trick

Resources