How to serve one page website via Apache .htaccess? - apache

Lets say I have developed one page application at example.com/index.html. How can I serve this file no matter what example.com/blabla is the URI. The requested URI should be preserved hence redirection is not an option.
RewriteEngine On
RewriteCond %{REQUEST_URI} !=/index.html
RewriteRule ^ /index.html [R=302]
Also setting it as an 404 document can apparently do the job but it is not the positive way.
ErrorDocument 404 /index.html
In my case it is custom one page application made with window.history.pushState but I am looking for proper way that is used for Angular.JS and Backbone.JS applications

Just one rule would be enough in site root/.htaccess; use FallbackResource:
FallbackResource /index.html

Related

How to setup request proxy using URL rewriting

I have an e-commerce site that resides in:
http://dev.gworks.mobi/
When a customer clicks on the signin link, the browser gets redirected to another domain, in order for authentication:
http://frock.gworks.mobi:8080/openam/XUI/#login/&goto=http%3A%2F%2Fdev.gworks.mobi%3A80%2Fcustomer%2Faccount%2Flogin%2Freferer%2FaHR0cDovL2Rldi5nd29ya3MubW9iaS8%2C%2F
I'm trying to rewrite http://dev.gworks.mobi/* to http://frock.gworks.mobi:8080/openam/*, without redirection.
I've tried this in the .htaccess of the dev.gworks.mobi site:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/openam(.*)$ [NC]
RewriteRule ^(.*)$ http://frock.gworks.mobi:8080/$1 [P,L]
</IfModule>
But when I access http://dev.gworks.mobi/openam, it shows a 404 page not found page.
Can anyone help me to achieve my use case?
Try this:
RewriteEngine on
RewriteBase /
# Make sure it's not an actual file being accessed
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Match the host
RewriteCond %{HTTP_HOST} ^dev\.gworks\.mobi
# Rewrite the request if it starts with "openam"
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [L,QSA]
This will rewrite all the requests to dev.gworks.mobi/openam to frock.gworks.mobi:8080.
If you want to mask the URI in a way that it's not visible to the visitor that she's visiting the authentication app, you need to add a P flag. Please note that it needs Apache's mod_proxy module in place:
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [P,L,QSA]
Feel free to drop the L flag, if it's not the last rewrite rule. See RewriteRule Flags for more information.
The 404
If it's all in place and you're still getting a 404 error, make sure that the target URL is not throwing 404 errors in the first place.
Second, check if you're still getting the error with the correct referrer URI set. It might be designed in a way to throw a 404, if the referrer is not correctly set. If that's the case, which I suspect, you need to use the R flag and redirect instead of proxying the request.
Last thing that comes to my mind, some webapps are not built in a way to figure out the URI address. The host, as well as the port number, might be hard-coded somewhere in the config files. Make sure that the authentication app is able to be run from another URL without the need to edit the configs.
Test
You can test the rewriterule online:

Tell Apache to always serve index.php, no matter what is in the URL

I have written a frontend SPA in Javascript. It uses Ember with its routing, fake URL, authentication and all the amazing stuff Ember handles almost implicitly.
The backend is written in PHP and the page shall be served by an Apache server.
Now, the page works just fine if the request is sent to the root file (aka index) and everything is handled from here. If I however reload the page at let's say localhost/login, Apache tries to find a file named login, which, naturally, doesn't exist, as everything is handled in Javascript and I get the widely-known 404 - The requested URL /login was not found on this server.
How do I tell Apache to always serve index.php, no matter what is in the URL?
It should look something like the default .htaccess for Laravel, which will always serve everything through the /index.php page without the actual /index.php in the url ex /index.php/login will be just /login, but it's worth noting that this will not force it through the /index.php page if the file exists.
# Checks if the rewrite mod is on.
<IfModule mod_rewrite.c>
RewriteEngine On
# Force everything through the index.php file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

htaccess | redirect 301 all files to homepage

Sorry to be asking yet another htaccess question but I have searched at length and can't crack it.
I have changed my website to a single page, www.mysite.com/index.html. Previously there were subdirectories and sub-subdirectories, all with a combination of html and other files in them.
I now want all file requests to be directed to the homepage, and for the homepage to display in the browser bar. Eventually I want to remove the old directories and images, but I'm assuming for now that Google needs me to keep them in order to transfer any ranking (is this right?).
There is just one exception to the rule that all traffic should go to www.mysite.com. I have bought another domain www.mysite2.com for SEO reasons. Currently this site has no hosting and is set to redirect to www.mysite.com. If users find www.mysite2.com, I would like them to see content from www.mysite.com but display the domain name www.mysite2.com.
This is the htaccess code I am currently using:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^([^?]*)$ /index.html?path=$1 [NC]
Options -Indexes
IndexIgnore *
RewriteCond %{HTTP_HOST} ^mysite.com
RewriteRule ^(.*) http://mysite2.com/$1 [P]
I have several questions/problems:
1) the www.mysite2.com redirect threw a 404 file not found error when i tried to access www.mysite.com. (I am having to test in live production... not great).
2) typing in www.mysite.com/products/ (former directory, still existing) takes me to www.mysite.com/// - it works but is unsightly.
3) typing in www.mysite.com/products/subdir/file.html still takes me to that original file
4) typing in www.mysite.com/lsdhfskdhf (i.e. a non-existent location) displays the homepage but continues to show the string.
5) typing in www.mysite.com/products/ksjdhfkdsjfh (i.e. non-existent location) displays the homepage but without any css formatting (!).
6) Should i be using Redirect 301 instead of RewriteRule? I heard that Google only likes 301 redirect.
I am a bit stuck and would welcome any help! Even if there is a comprehensive guide somewhere to whatever language apache is using in its directories that would be good. Lots of sites claim to this but i haven't found a good one.
Apologies for length.
Thanks
Emma

How to rewrite all 404's to index.php using cPanel URLs?

I'm trying to rewrite all 404's to index.php where I use PHP's parse_url() to determine which file to include (e.g. about-us.php, contact-us.php) and I'm getting some really weird results.
I'm working on a 'dev' URL automatically created by cPanel:
http://xxx.xxx.xxx.xxx/~mySite/
Current Method
My .htaccess file contains the following:
RewriteEngine on
RewriteBase /~mySite
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_.]+)$ index.php
And the results are a mixed bag:
xxx.xxx.xxx.xxx/~mySite/contact-us renders just fine.
xxx.xxx.xxx.xxx/~mySite/contact-us/phone throws a 404 that isn't caught by mod_rewrite.
xxx.xxx.xxx.xxx/~mySite/about-us rewrites to the server root (xxx.xxx.xxx.xxx/index.php).
Previously Tried
ErrorDocument 404 /~mySite/index.php
And I get the similar results, except for the following:
xxx.xxx.xxx.xxx/~mySite/contact-us/phone rewrites to index.php but all my CSS and JS includes are off because they're trying to load relative to /~mySite/contact-us instead of /~mySite.
Any help? I'm going out of my mind. Especially the fact that contact-us works fine, but about-us doesn't?
First don't use cPanel preview. That is not a good way to view your dev site. Who knows how it will affect the rules. Also control panels do weird things anyway.
Preview your site using your real site domain name. You can do that my modifying your HOST file on your computer so that only you can view it by the domain name. This little guide will show you how to edit it. It takes like 2 minutes.
Then that should help to check things better.
Most likely why the error document doesn't work because ~mySite is most likely not your document root. That is typically how cpanel does it's preview links. So your real error document should probably be as Marc B stated.
ErrorDocument 404 /index.php
If you want a mod_rewrite solution, this should also work. But I wouldn't use both.
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ / [R=301,L]
On a side note, I think it's usually good to use a 404 page so that users know that the requested page is not a real page instead of some people thinking something is just wrong with your site because it redirects to the home page. Like facebook, it gives you a big thumbs up with a bandage on it saying it the page is not available. I've seen many custom 404 pages that were pretty clever so maybe it might be time to just get creative.

SEO optimization - front page appears twice?

Web server has initial page in the file, let's say, somefile.html. .htaccess file has the following instruction:
DirectoryIndex somefile.html
which makes web server to fetch contents of somefile.html when web server's root is requested.
However, some page(s) of the website may refer to somefile.html, which contains exactly the same content as server's root. Thus this situation leads to same contents appearing on the web server twice - when somefile.html is requested, and when / is requested.
How to best correct situation with least effort while keeping website structure?
Add a 301 redirect to your htaccess file in your document root (preferably before any rules you may already have:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^\ ]*)somefile\.html
RewriteRule ^ /%1 [L,R=301]
This redirects any direct request for /somefile.html to just /. As well as any subdirectories: /foo/bar/somefile.html to /foo/bar/.