Angular 2 Routing, .htaccess - .htaccess

I am having some problems with my routeing. It works fine on localhost but when I put it on the server and do a refresh of the page I get a 404 Error.
So I made an .htaccess file and put it in the same place as my index.html:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
But it is still not working what am I doing wrong?
Do I have to add something to my Angular routeing?
Can someone help?

RewriteRule ^ /index.html
Try removing the slash prefix on the RewriteRule substitution. For example:
RewriteRule ^ index.html [L]
This is now relative to the current directory (where the index.html file is located), rather than the document root.
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
Note the cause of your problem, but %{DOCUMENT_ROOT}%{REQUEST_URI} is the same as %{REQUEST_FILENAME}, so it is more common to see this written as:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
However, it would be more efficient to prefix this with a check for file extensions of known assets to avoid having to check every request to see if it is a file or a directory (which is relatively expensive). For example:
# Allow any request for CSS, JS and images straight through...
RewriteRule .\.(css|js|jpe?g|png|gif) - [L]

Related

.htaccess serving other files if specific files are not found

If I have /index.html and the user goes to domain.tld or domain.tld/index.html I want them to get that page. (Default behavior)
If I don't have /index.html but I do have /content.txt I'd like to serve the page /makeindex.php but not change the url.
If I don't have /index.html or /content.txt I'd like to serve /nocontent.php but not change the url.
So far I have:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /makeindex.php [L]
But I don't know how to limit this to domain.tld or domain.tld/index.html and I also don't know how I would create that two step process first checking for content.txt if I serve /makeindex.php or falling back to /nocontent.php if both those files don't exist.
You can use the following rule, put this at the top of your htaccess :
RewriteEngine on
#if /index.html exists serve it as a directory index and main page
RewriteCond %{DOCUMENT_ROOT}/index.html -f
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^ /index.html [L]
#if content.txt exists , use makeindex.php as directory index
RewriteCond %{DOCUMENT_ROOT}/content.txt -f
RewriteRule ^$ /makeindex.php [L]
#else set /nocontent.php as directory index
RewriteRule ^$ /nocontent.php [L]

Splitting url by nth characters

I have a site that is getting too much traffic and I want to cache some of the pages, which should alleviate the problem.
I have a system for this in place already, but the issue is the url structure would lead to 11.365 million pages being saved in one directory, e.g.
dir/* <- 11+ million pages saved in this directory.
And this will make things very difficult when it comes to deleting the directory.
Via a predictive search I am using JavaScript to split down the cache like:
people/joh/n-j/one/s.json
Which is more manageable to delete.
Is there anyway I can use mod_rewrite to split urls down in the same way, e.g.
User loads /people/john-jones
Use mod_rewrite to see if caches/html/people/joh/n-j/one/s.html exists, if so server it
Else go to PHP an generate the page
I have a rule for this already, but not with splitting:
RewriteCond %{SCRIPT_FILENAME} ^(.+)\/cache [NC]
RewriteRule .* - [E=PATH:%1]
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^.+ %{ENV:PATH}/index.php?request=a&c=search&m=people&p=$0 [L]
Give the following rules a try:
RewriteEngine On
RewriteRule ^(people/.*?)([^/]{3})([^/]+)$ /$1$2/$3 [R=302,L]
RewriteCond %{DOCUMENT_ROOT}/caches/html%{REQUEST_URI}.html -f
RewriteRule ^ %{DOCUMENT_ROOT}/caches/html%{REQUEST_URI}.html [L]
The suggested edit by OP was rejected in peer review. Here's the solution OP went with:
# Set an environmental var for the root directory, so it works on local dev and live servers
RewriteCond %{SCRIPT_FILENAME} ^(.+)\/index.php$ [NC]
RewriteRule .* - [E=PATH:%1]
# Pick up the actual request from query string and set it as an environmental var
RewriteCond %{QUERY_STRING} ^request=names\/(.*?)([^/]{3})([^/]+) [NC]
RewriteRule .* - [E=SN:%1%2/%3]
# If a cache paged exists, internal redirect to that
RewriteCond %{ENV:PATH}/cache/html/names/%{ENV:SN}.html -f
RewriteRule .* cache/html/names/%{ENV:SN}.html [L]
# Send requests that are not cached to php
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^.+$ index.php?request=$0 [QSA,L]

Apache Rewrite module, complex rules

I basically want to redirect all requests to index.php doesn't matter what, except those with certain REQUEST_URI. Those requests that look like image files, so have an ending like: .jpg or .png should be examined and if they are under the public/ folder (or any subfolders in any depth) and if they are they should be served and the rewriting process should stop here! If not, I want to redirect to a default image at public/errors/image-not-found.png and terminate rewriting process. The other exceptions are files that end with .js, .css, .html or .swf. They also should only be served if they are located under the public/ folder or any other subfolders. If not, a simple 404-Not found should be sent back. In either case of the last to the rewriting process need to stop of course.
Any other request should be redirected to index.php and appended as a query string. (even if the request points to a directory or to a file that is not under the conditions aforesaid, but exists, e.g: www.xyz.com/library/Database.php -> www.xyz.com/index.php?url=library/Database.php)
I have half-measure solution:This is how I redirect everything to index.php:
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
I append a visual explanation of what I want. Maybe this is clearer:
Basically, you don't want to do anything if the requested file exists in public/ or any of its subfolders. So, first we deal with those:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/public/.*\.(html|css|js|swf|jpe?g|png|gif|bmp|ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
Now, that is over with. We now check whether an image was requested:
RewriteCond %{REQUEST_URI} \.(jpe?g|png|gif|bmp|ico)$ [NC]
RewriteRule ^ /public/errors/image-not-found.png [R,L]
Similarly for other static files:
RewriteCond %{REQUEST_URI} \.(html|css|js|swf)$ [NC]
RewriteRule ^ - [R=404,L]
Redirect everything now to index.php:
RewriteCond %{REQUEST_URI} !/index\.php$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^.*$ /index.php?url=$0 [R,L]
Following series of rules should probably mimic the flow-chart:
# for public folder pass through
RewriteRule ^public/.+?\.(?:jpe?g|ico|png|bmp|css|js|html|swf)$ - [L,NC]
# for other images
RewriteRule ^.+?\.(?:jpe?g|ico|png|bmp)$ /public/errors/img-not-found.jpg [L,NC,R=302]
# for other css|js|html|swf URIs
RewriteRule ^.+?\.(?:css|js|html|swf)$ - [L,NC,R=404]
# everything else, route to index.php
RewriteRule ^((?!index\.php).+)$ index.php?url=$1 [NC,QSA,L]

.htaccess doesn't rewrite relative to the root directory

I have tried to create an .htaccess file to do following:
Direct www.domain.com/name or www.domain.com/name/ to www.domain.com/page.php?id=name
and www.domain.com/name/2 or www.domain.com/name/2/ to www.domain.com/page.php?id=name&pg=2
my .htaccess looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid link
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([a-z0-9-_\.]+)/?$ page.php?id=$1 [L]
RewriteRule ^([a-z0-9-_\.]+)/([a-z0-9]+)/?$ page.php?id=$1&pg=$2 [L]
</IfModule>
The problem is, that when I actually use a slash after name it thinks of it as a directory and looks for pages in www.domain.com/name/.. But I am still able to $_GET the variables based on id and pg.
Can anyone tell me what I have done wrong? I prefer that the URL in the address bar stays clean as www.domain.com/name/2/.
Also i have another question.. I have tried to rewrite the other URLS without luck.
If they write: www.domain.com/page.php?id=name&pg=2 and want to change the address bar URL to be be clean again, but that completely went wrong for me. Is there any specific way to do this by using what I have already made?
Thanks in advance for your help.
EDIT
The solution was based on PHP and not .htaccess. The answer was found based on this question: Stylesheet does not load after using RewriteRule and include . My problem was caused by PHP including relative to the public URL and directory. I have been forced to define a main URL variable to place before any foreign includes.
RewriteCond is only applicable to the very next RewriteRule.
Have your code this way:
RewriteEngine On
RewriteBase /
# If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
# If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
# If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} \s/+page\.php\?id=([^\s&]+) [NC]
RewriteRule ^ %1? [R=302,L]
RewriteRule ^([\w.-]+)/?$ page.php?id=$1 [L,QSA]
RewriteRule ^([\w.-]+)/([\w.-]+)/?$ page.php?id=$1&pg=$2 [L,QSA]

Subdirectory URL rewriting PHP

Setup
I have my file structure set up as so:
/root
|
/api
|
/Slim PHP framework
index.php
|
index.php
The index.php inside the Slim directory contains the routes required to retrieve the JSON data from a Mongo database. E.g.
$app->get('/users(/:id)', function($id = null) use ($app, $collection) {
/* Do mongo search and echo json_encoded data back */
});
I have an .htaccess file contains: which removes the .php extension from files under the root.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php`
Question
I can access my JSON data using url: http://localhost:8888/root/api/index.php/users.
However, what I would like to do is access the data using the url: http://localhost:8888/root/api/users
If I understand correctly, what about this?
RewriteRule ^api/users/(.*)$ /root/api/index.php/users/$1 [L]
RewriteRule ^api/users$ /root/api/index.php/users [L]
That should allow this URL.
http://localhost:8888/api/users/1
and it will allow this too
http://localhost:8888/api/users
EDIT:
That should allow you to add a number after users. Also shortened the URL so you don't have to include root in the URL as well.
Assuming, your .htacces is located in website root "/"
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteCond %{REQUEST_URI} !/index.php [NC]
RewriteRule ^(.*?/api)/(.*)$ $1/index.php/$2 [NC,L]
This would redirect
http://localhost/root/api/users/1 => http://localhost/root/api/index.php/users/1
http://localhost/root/api/data/20 => http://localhost/root/api/index.php/data/20
One thing of note, the sequence of rules is also important, so if you need to rewrite/redirect http://example.com/users AND http://example.com/users/ to http://example.com/userinfo/ while at the same time rewriting http://example.com/users/uname to http://example.com/scripts/script.php?id=uname then this one should work: RewriteEngine on
RewriteEngine on
RewriteRule ^users/$ /userinfo/ [L]
RewriteRule ^users/(.*)$ /scripts/script.php?id=$1 [L]
RewriteRule ^users$ /userinfo/ [L]
There could be a better solution with one line less but this one works for me.

Resources