Using htaccess to redirect to certain extension - .htaccess

I want to know how to use .htaccess to redirect a certain path to a certain extension. To be more clear, I want to redirect something like this:
http://www.example.com/api/some/page
To this:
http://www.example.com/some/page.json
I understand that I could just do this using the router that is supplied by CakePHP, however, how would this be done with a .htaccess file?

To handle this rewrite, you may use this rule just below RewriteEngine On:
RewriteEngine On
RewriteRule ^api/(?!.+\.json$)(.+)$ $1.json [L,NC]
(?!.+\.json$) is a negative lookahead that skips matching URIs that end with .json (to avoid a rewrite loop)
Pattern ^api/(?!.+\.json$)(.+)$ matches URIs that start with /api/ and captures part after /api in $1
$1.json in target adds .json at the end of matched part
Flags: L is for Last and NC is Ignore case

Related

.htaccess regex redirect avoid by file type

I have two URL conditions and I wanted to redirect them like this:
https://www.example.com/feeds/4aceXy to https://www.example.com/direct_feed/4aceXy
Now the problem is, I am also using the URL for an older link like this one:
https://wwww.example.com/feeds/5bdb39711b41d479273e678a6f356603d7109ffc.xml
I wanted to avoid redirect with .xml extension here is my current redirect:
RewriteRule feeds/(.*)?$ https://wwww.example.com/direct_feed/$1 [QSA,L]
It works fine but I don't want to redirect it with .xml based URL.
My question is - is there a condition that can help me to avoid the rewrite if a parameter contains .xml in regX (.*)?$
You can use a negative lookbehind:
RewriteRule feeds/(.*)?(?<!\.xml)$ https://wwww.example.com/direct_feed/$1 [QSA,L]

How can i 301 redirect a subfolder and everything after it?

I am trying to redirect a subfolder as well as anything after it to the home page.
For example:
example.com/subfolder/extra-stuff > example.com
The extra-stuff is constantly changing and auto generated, so I want the redirect to remove that as well.
I am using:
Redirect 301 /subfolder(.*) http://www.example.com
However, this will result in http://www.example.com/extra-stuff.
Is there a way I can say if /subfolder(and anything else after subfolder) redirect to home?
Thanks for any suggestions!
The Redirect directive uses simple prefix-matching and everything after the match is copied onto the end of the target URL (which is what you are seeing here). However, the Redirect directive also does not support regex syntax, so a "pattern" like (.*) on the end will actually match the literal characters (, ., * and ) - which shouldn't have worked in your example?!
You'll need to use RedirectMatch instead (also part of mod_alias), which does use regex, and is not prefix matching.
For example:
RedirectMatch 301 ^/subfolder http://www.example.com/
Any request that starts /subfolder will be redirected to http://www.example.com/ exactly.
You'll need to clear your browser catch before testing.
You tagged your question "Magento" (which is probably using mod_rewrite). You should note, however, if you are already using mod_rewrite for rewrites/redirects then you should probably be using mod_rewrite instead of mod_alias to do this redirect, since you can potentially get conflicts.
For example, the equivalent mod_rewrite directive would be:
RewriteRule ^subfolder http://www.example.com/ [R=301,L]
Note there is no slash prefix on the RewriteRule pattern. This would need to go near the top of your .htaccess file.

Rewrite rule for name.123456.js in htaccess

I have this file in my webserver:
http://example.com/static/js/min/common.min.js
Since all files inside /static/ are cached with CloudFlare's Edge Cache, I need a way to change the url with something like this, so if the file is modified, the new version will be automatically fresh served:
http://example.com/static/js/min/common.min.1234567890.js
Where 1234567890 is the timestamp of the file's date modification. I already generate the filename according to the modification date, the issue I'm having is in the .htaccess file.
This works fine:
RewriteRule ^(.*)\.[\d]{10}\.(js)$ $1.$2 [L]
That means that:
http://example.com/static/js/min/common.min.1234567890.js
Is redirected to:
http://example.com/static/js/min/common.min.js
But, that will catch all .js requests from the domain, I just want to catch .js requests from within /static/js/min/*.js -- but this is failing:
RewriteRule ^static/js/min/(.*)\.[\d]{10}\.(js)$ $1.$2 [L]
What should the rule be like?
From your question,
You want to redirect
http://example.com/static/js/min/common.min.1234567890.js
to
http://example.com/static/js/min/common.min.js
So, How to do that
the .htaccess
First add
RewriteEngine On
To turn on the rewrite engine
Then the next important line comes
RewriteRule ^static/js/min/([^\d]*)(\d{10}).js$ static/js/min/$1js [L]
Explanation
Set the path as static/js/min/
Then we use RegEx to take the string until a non digit. ([^\d]*).
That is common.min. is captured.
Now $1 is common.min.
Then to match the url, we use (\d{10}) to capture the digits.
That is 1234567890 is captured.
Now $2 is 1234567890 which we don't want anymore
Then redirect to
static/js/min/$1js
Not that here we didn't added the . after the $1 because $1 ending with a . (common.min.)
So, the code will be
RewriteEngine On
RewriteRule ^static/js/min/([^\d]*)(\d{10}).js$ static/js/min/$1js [L]
Working Screenshot
My File Structure
The Address in Browser

mod_rewrite for a 301 redirect. Not redirecting to proper location

I'm trying to use a RewriteRule (using ISAPI, NOT on an Apache server) to 301 redirect a url such as:
http://www.mydomain.com/news/story-title/
to
http://www.mydomain.com/news/detail/story-title/
What I've gotten so far is:
RewriteRule ^news/(?!detail)/?$ news/detail/$1/ [L,R=301]
which successfully ignores urls that already have the "detail" in them (in some of my first attempts I ended up with a loop and a url like "/news/detail/detail/detail..."), but visiting /news/story-title/ gives me a 404 so it's not redirecting to the proper location.
Change your rewrite rule to
RewriteRule ^news/(?!detail)([^/]+)/?$ news/detail/$1/ [L,R=301]
EDIT : (How it works?)
/(?!detail) is a negative lookahead but it's also non-capturing i.e. it matches / but not what comes after it; just makes sure that it isn't "detail". So, I added a capturing group ([^/]+) to capure those characters (one or more + of anything that's not a/) optionally ending with a /.
Hence, the $1 now gets replaced with the matched directory name.

.htaccess 301 Redirect Appending Query's to End of URL

I am hoping someone can help with an unusual situation.
I have one main rewrite rule in place in my httpd.conf file which handles all of our dynamic content. The rule looks like this and works fine:
RewriteRule ^(.)(/./d/[^.]*)$ /category/refine.cgi\?\&a\=$2
The problem I have is that when I try to use .htaccess to create a simple 301 redirect, the query parameters are automatically appended to the end of the URL's so the final result looks like this:
http://www.example.com/category/page.html?&a=/category/subcategory/something/d/page/
Notice that the query string is appended to the URL when using .htaccess to create a 301 redirect.
I have solution for this on a case-by-case basis, but it's not practical to create a new rule each time I want to do a simple 301 redirect.
So, I am wondering if I can edit my "main rule" in any way so that when .htaccess is used to create redirects, the query parameters are not appended to the target URL.
Thanks in advance for any help you can provide.
If you have multiple simple redirects for which you want to suppress query string values you could put all the redirects in a RewriteMap (since you already have access to httpd.conf), and have one .htaccess rule that suppresses the query strings as below
place in htaccess
#if there is a match in the map
RewriteCond ${redirect_map:$1} !=""
RewriteRule ^(.*)$ ${redirect_map:$1}? [R,L]
place in httpd.conf
RewriteEngine On
RewriteMap redirect_map txt:/usr/local/apache/conf/redirect.map
contents of /usr/local/apache/conf/redirect.map
key followed by a space followed by target
directory/subdirectory1/subdirectory2/ example/category7/subdirectory/file.html
directory4/subdirectory2/subdirectory9/ example/category5/subdirectory4/file332.html
That's what your rule has defined it to do:
RewriteRule ^(.)(/./d/[^.]*)$ /category/refine.cgi\?\&a\=$2
It says to create a URL that will look like:
category/refine.cgi?&a=/foo/bar/
If you don't want that to happen, change your rule to be:
RewriteRule ^(.)(/./d/[^.]*)$ /category/refine.cgi\?

Resources