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
Related
Hoping this isn't a duplicate, done a lot of looking and I just get more confused as I don't use .htaccess often.
I would like to have some pretty URLs and see lots of help regarding getting information where for example index.php is passed a parameter such as page. So I can currently convert www.example.com/index.php?page=help to www.example.com/help.
Obviously I'm not clued up on this but I would like to parse a URL such as www.example.com/?page=help.
Can't seem to find much info and adapting the original I am obviously going wrong somewhere.
Any help or pointers in the right direction would be greatly appreciated. I'm sure its probably stupidly simple.
My alterations so far which do not seem to work are:
RewriteCond %{THE_REQUEST} ^.*/?page=$1
RewriteRule ^(.*)/+page$ /$1[QSA,L]
Also recently tried QUERY_STRING but just getting server error.
RewriteCond %{QUERY_STRING} ^page=([a-zA-Z]*)
RewriteRule ^(.*) /$1 [QSA,L]
Given up as dead to the world so thought I would ask. Hoping to ensure the request/url etc starts ?page and wanting to make a clean URL from the page parameter.
This is the whole/basic process...
1. HTML Source
Make sure you are linking to the "pretty/canonical" URL in your HTML source. This should be a root-relative URL starting with a slash (or absolute), in case you rewrite from different URL path depths later. For example:
Help Page
2. Rewrite the "pretty" URL
In .htaccess (using mod_rewrite), internally rewrite the "pretty" URL back to the file that actually handles the request, ie. the "front-controller" (eg. index.php, passing the page URL parameter if you wish). For example:
DirectoryIndex index.php
RewriteEngine On
# Rewrite URL of the form "/help" to "index.php?page=help"
RewriteRule ^[^.]+$ index.php?page=$0 [L]
The RewriteRule pattern ^[^.]+$ matches any URL-path that does not include a dot. By excluding a dot we can easily omit any request that would map to a physical file (that includes a file extension delimited by a dot).
The $0 backreference contains the entire URL-path that is matched by the RewriteRule pattern.
The DirectoryIndex is required when the "homepage" (root-directory) is requested, when the URL-path is otherwise empty. In this case the page URL parameter is not passed to our script.
3. Implement the front-controller / router (ie. index.php)
In index.php (your "front-controller" / router) we read the page URL parameter and serve the appropriate content. For example:
<?php
$pages = [
'home' => '/content/homepage.php',
'help' => '/content/help-page.php',
'about' => '/content/about-page.php',
'404' => '/content/404.php',
];
// Default to "home" if "page" URL param is omitted or is empty
$page = empty($_GET['page']) ? 'home' : $_GET['page'];
// Default to 404 "page" if not found in the array/DB of pages
$handler = $pages[$page] ?? $pages['404'];
include($_SERVER['DOCUMENT_ROOT'].$handler);
As seen in the above script, the actual "content" is stored in the /content subdirectory. (This could also be a location outside of the document root.) By storing these files in a separate directory they can be easily protected from direct access.
4. Redirect the "old/ugly" URL to the "new/pretty" URL [OPTIONAL]
This is only strictly necessary (in order to preserve SEO) if you are changing an existing URL structure and the "old/ugly" (original) URLs have been exposed (indexed by search engines, linked to by third parties, etc.), otherwise the "old" URL (ie. /index.php?page=abc) is accessible. This is the same whenever you change an existing URL structure.
If the site is new and you are implementing the "new/pretty" URLs from the start then this is not so important, but it does prevent users from accessing the old URLs if they were ever exposed/guessed.
The following would go before the internal rewrite and after the RewriteEngine directive. For example:
# Redirect "old" URL of the form "/index.php?page=help" to "/help"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/index\.php$ [OR]
RewriteCond %{QUERY_STRING} ^page=([^.&]*)
RewriteRule ^(index\.php)?$ /%1 [R=301,L]
The check against the REDIRECT_STATUS environment variable prevents a redirect-loop by not redirecting requests that have already been rewritten by the later rewrite.
The %1 backreference contains the value of the page URL parameter, as captured from the preceding CondPattern (RewriteCond directive). (Note how this is different to the $n backreference as used in the rewrite above.)
The above redirects all URL variants both with/without index.php and with/without the page URL parameter. For example:
/index.php?page=help -> /help
/?page=help -> /help
/index.php -> / (homepage)
/?page= -> / (homepage)
TIP: Test first with 302 (temporary) redirects to prevent potential caching issues.
Comments / improvements / Exercises for the reader
The above does not handle additional URL parameters. You can use the QSA (Query String Append) flag on the initial rewrite to append additional URL parameters on the initially requested URL. However, implementing the reverse redirect is not so trivial.
You don't need to pass the page URL parameter in the rewrite. The entire (original) URL is available in the PHP superglobal $_SERVER['REQUEST_URI'] (which also includes the query string - if any). You can then parse this variable to extract the required part of the URL instead of relying on the page URL parameter. This generally allows greatest flexibility, without having to modify .htaccess later.
However, being able to pass a page URL parameter can be "useful" if you ever want to manually rewrite (override) a URL route using .htaccess.
Incorporate regex (wildcard pattern matching) in the "router" script so you can generate URLs with "parameters". eg. /<page>/<param1>/<param2> like /photo/cat/large.
Reference:
https://httpd.apache.org/docs/2.4/rewrite/
https://httpd.apache.org/docs/2.4/rewrite/intro.html
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
RewriteCond %{QUERY_STRING} ^page=([^&]+)
RewriteRule ^$ /%1? [R=302,L]
Can't delete and didn't want to waste anyones time responding.
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]
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
I am setting up a MVC style routing system using mod rewrite within an .htaccess file (and some php parsing too.)
I need to be able to direct different URLs to different php files that will be used as controllers. (index.php, admin.php, etc...)
I have found and edited a rewrite rule that does this well by looking at the first word after the first slash:
RewriteCond %{REQUEST_URI} ^/stats(.*)
RewriteRule ^(.*)$ /hello.php/$1 [L]
However, my problem is I want it to rewrite based on the 2nd word, not the first. I want the first word to be a username. So I want this:
http://www.samplesite.com/username/admin to redirect to admin.php
instead of:
http://www.samplesite.com/admin
I think I just need to edit the rewrite rule slightly with a 'anything can be here' type variable, but I'm unsure how to do that.
I guess you can prefix [^/]+/ to match and ignore that username/
RewriteCond %{REQUEST_URI} ^/[^/]+/stats(.*)
RewriteRule ^[^/]+/(.*)$ /hello.php/$1 [L]
then http://www.samplesite.com/username/statsadmin will be redirecte to http://www.samplesite.com/hello.php/statsadmin (or so, I do not know the .htaccess file)
To answer your question, "an anything can be here type variable" would be something like a full-stop . - it means "any character". Also the asterisk * means "zero or more of the preceding character or parenthesized grouped characters".
But I don't think you need that...If your matching url will always end in "admin" then you can use the dollar sign $ to match the end of the string.
RewriteRule admin$ admin.php [R,NC,L]
Rewrites www.anything.at/all/that/ends/in/admin to www.anything.at/admin.php
I have a folder named /test in my application.
Right now i am trying to write an .htaccess file that would show all requests to /test* as /test.
For example:
www.example.com/test/ is the actual directory with index.php file in it.
All the requests like the following should go to the same /test directory
www.example.com/test-hello/
www.example.com/test-world/
www.example.com/test-htacess/
www.example.com/test123/
Basically any requests to /test* should go to /test.
This is what I've tried so far:
RewriteRule ^/test* /test
You need to use RewriteCond to first match "test in url"
Try below:
RewriteCond %{THE_REQUEST} ^GET\ /test/
RewriteRule ^test/(.*) /test/$1 [L,R=301]
Your regular expression is wrong. You mean ^/test.*$. Your rule would match to /testtttt.
The asterisk means that the char in front of it can be zero or more times included. The dot is a special char which means here could be anything. the .* matches every string including an empty string. See also Wikipedia.
You currently are not putting the -hello, -world etc behind your folder. What is hello? Is that the file? Or the param?
The second part of the rewriteRule should be a file. Something like
RewriteRule ^/test(.*)$ /test/$1.php
Above function will have:
/testABC to /test/ABC.php
But I don't understand what you want to accomplish?