.htaccess rewrite to index.php or index.html based on condition - laravel

I'm not so good with htaccess and tried to find an answer to my question but no luck so far.
So I have this .htaccess rewrite:
RewriteCond %{REQUEST_URI} /(api|nova|nova-api)
RewriteRule .* /index.php
Which works well.
The website is an Angular site where I have dynamic URLs which are routed by JS.
So if I open base domain: example.com works well because index.html is served.
But if I open a route like: example.com/example-route. It says 404.
Could you please help me how should I modify the .htaccess file?

RewriteCond %{REQUEST_URI} /(api|nova|nova-api)
RewriteRule .* /index.php
You would seem to just need to rewrite the request to index.html after your API rewrite to index.php. However, you should modify your existing rule to add the L flag and the regex that matches the request should be anchored (although the condition is not required at all since the URL check should be performed in the RewriteRule directive itself).
For example, try the following instead:
# "index.html" needs to take priority when requesting the root directory
DirectoryIndex index.html
# Abort early if request is already "index.html" or "index.php"
RewriteRule ^index\.(html|php)$ - [L]
# Rewrite certain requests to Laravel API
RewriteRule ^(api|nova|nova-api)($|/) index.php [L]
# Rewrite everything else to Angular
# (unless it already maps to a file or directory)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
Since the "homepage" is already working OK, it would suggest DirectoryIndex is already set OK in the server config (and prioritising index.html), although explicitly setting this to just index.html (as above) is more optimal, if this is all that's required.

Related

How to set a RewriteCond for a certain page URL

I have implemented a mod rewrite condition as shown below. Basically I want everyone other than me (from the stated IP address) to be redirected to a certain page on my site. That part works but these directives end up causing endless redirects and the browser times-out.
What might a RewriteCond directive look like to test the page /index.html and not do anymore rewrites if the page is https://example.com/index.html?
# 2016-03-18 redirect everyone except listed IPs
# 123.456.789.012 = my static Work Office address
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^(123\.456\.789\.012)$
RewriteRule ^(.*)$ https://example.com/index.html [R=302,L]
You have to exclude the destination you are redirecting to :
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^(123\.456\.789\.012)$
RewriteCond %{REQUEST_URI} !^/index\.html
RewriteRule ^(.*)$ https://example.com/index.html [R=302,L]
Otherwise you will get a redirect loop error because index.htm also matches the pattern ^(.*)$ .

How do I strip out ?_escaped_fragment_= using .htaccess

Google discovered that I'm allowing end users to navigate my content using ajax loading, and is loading my pages as a user client rather than requesting them as new page loads. So instead of trying to index www.mysite.com/page, it's requesting www.mysite.com/?_escaped_fragment_=/page
Which is not at all what I want it to do. My snapshots are served at the same URL as the ajax-loaded content. The site is not using queries, it's not supporting them and I don't want to build that support. This means that all the pages look broken to google which of course is unfortunate!
Currently all page requests are redirected server side using .htaccess sending requests to the index.php file which in turn compiles the html doc on the server before serving to the client. The site serves perfectly valid and unique html documents for all pages. But google insists on doing it the ajax way and adding the query which always returns a broken page.
I'm not a .htaccess expert, but it seems to me that the easiest way to solve this would be to rewrite the request, remove the ?_escaped_fragment_=/ bit and permanently redirect any such requests to what currently works which is to load the pages using their correct url's.
Anyone know how I would go about doing that? Below is the current redirect part of my .htaccess file which needs to be amended with the _escaped_fragment_ stripping code:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
#if trailing / remove it with a permanent redirect
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
#if missing www. add it with a permanent redirect
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
#requests for index.php never rewritten
RewriteRule ^index\.php$ - [L]
#if file or directory are missing, route to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
This is how I rewrote it so that all ?_escaped_fragment_=/XXXXX requests got redirected to /XXXXX without the query
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%1? [L,R=301]
This makes www.domain.com/?_escaped_fragment_=/somepage redirect (permanently) to www.domain.com/somepage
...which is just what I wanted.

301 URL Forwarding with HTACCESS or PHP

Just curious if anyone can help me on this HTACCESS issue.
I have these OLD URLS that need to get forwarded properly.
Previous structure
domain.com/Canada/Accounting
domain.com/Canada/Trades
domain.com/Canada/Sales
Proper structure
CATEGORY - /jobs/accounting-jobs
LOCATION - /jobs/jobs-kelowna
TOGETHER - /jobs/accounting-jobs-kelowna
Domain Structure
domain.com/jobs/[category]-jobs-[location]
Is this possible, either by HTACCES or PHP...just don't want these 404'ed pages.
I have 86+ to do, if there is a good way to forward these.
This is what I have, but i'm unable to successfully forward the bad-urls properly.
OLD
/browse
/Toronto/
/Canada/Administrative
/Vancouver/
/Canada/Trades
/Calgary/
/Canada/Hospitality
This is my HTACCESS right now.
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
#
# Trailing slash check
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule ^(.*)$ $1/ [L,R=301]
#
# PAGES
RewriteRule ^add-job/?$ /add-job.php [L]
RewriteRule ^jobs/?$ /results.php [L]
RewriteRule ^sitemap/?$ /sitemap.php [L]
#
# SEARCH
# CATEGORY - accounting-jobs
# LOCATION - jobs-kelowna
# TOGETHER - accounting-jobs-kelowna
RewriteRule ^jobs/([a-zA-Z0-9_-]+)/([0-9]+)?$ results.php?whatwhere=$1&page=$2
RewriteRule ^jobs/([a-zA-Z0-9_-]+)/([0-9]+)/?$ results.php?whatwhere=$1&page=$2
To 301 redirect your pages you can do something like:
RewriteEngine On
RewriteBase /
RewriteRule ^(\w+)/(\w+)$ /jobs/$2-jobs-$1 [R=301,L]
This only addresses the urls from your previous structure (the combinations, you have not shown any previous urls with just location or category) but note that Canada will stay Canada, it does not become canada. You can change everything to lower case using rewrite as well.
You also have to take care that you don't rewrite any of the current urls but without more information, this should do it.
Edit: For the location-only urls you could use a rule like:
RewriteRule ^(\w+)/$ /jobs/jobs-$1 [R=301,L]
Again, you need to look out that your rewrite rule does not interfere with your current urls. If that is the case, you would need to redirect every old url manually.
For lower-case new urls, you should search SO, there are some questions with good answers about converting a mized-case variable to lower-case.
If you have mod_rewrite, you can add these lines to your .htaccess file:
RewriteEngine on
RewriteRule ^Canada/Accounting$ /jobs/accounting-jobs [R,L]
However, it's not clear from your question exactly what you want mapped. Are the 3 previous URLs supposed to redirect to the 3 new ones? They don't seem to be equivalent.

Rewrite link rule, conflicting files and folders

Been trying to resolve this problem with a rewrite rule that assigns a subdomain to a root directory of the same name, for example.
ddd.example.com will link to "/_projects/ddd" directory, that works fine and I have no trouble with it, the issue is that any files or directories I have in the root directory "/" can be accessed from the subdomain ddd.example.com.
Here is an example directory structure
example.com = "/"
"index.php"
ddd.example.com = "/_projects/ddd"
no files
So if for instance I access ddd.example.com/index.php, it will resolve to using the file located example.com/index.php which is located a directory below.
Here is the rewrite rule for .htaccess
# Skip rewrite if subdomain is www
RewriteCond %{HTTP_HOST} !^www\. [NC]
# Extract (required) subdomain to %1
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com(:80)?$
# Redirect to domain if requested URL does not resolve to existing subdirectory path
RewriteCond %{DOCUMENT_ROOT}/_projects/%1 !-d
RewriteRule (.*) http://example.com/ [NC,R=301]
# Skip rewrite if subdomain is www
RewriteCond %{HTTP_HOST} !^www\. [NC]
# Extract (required) subdomain to %1
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com(:80)?$
# Skip rewrite if requested URL does not resolve to existing subdirectory path or file
RewriteCond %{DOCUMENT_ROOT}/_projects/%1/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/_projects/%1/$1 -d
RewriteRule (.*) /_projects/%1/$1 [NC,L]
What if your RewriteConds fail? Then the URL falls through and is not rewritten. And so it accesses the document root. I would just create separate VirtualHost entries for every single supported subdomain. (How many are there?)
Suppose the client asks for http://sub.example.com/index.php.
Suppose that there exists an /_projects/sub/index.php.
Your RewriteCond-s will see that /_projects/sub/index.php exists as a file, and then skip the rewrite. But if the rewrite is skipped, then there is no redirect to /_projects/sub/. So what document is fetched in that case? You guessed it, /index.php.
You should unconditionally redirect these subdomains to their proper places (subject only to checks against looping).
Why did you split the rewrite into two, one doing an internal redirect? The internal redirect isn't rewriting the whole URL to example.com, and so it stays in the subdomain. It looks like you can get into a loop there.
My attempt at rewriting was to do this essentially.
Pseudo Code:
if (subdomain-directory != exists)
redirect them to the home page
else
rewrite the request for the subdomain
I could only accomplish that using two rules, I haven't found any other way to accomplish this, so this was my attempt.
The condition in question actually works fine, if I have an index.php in the /_projects/sub directory then it will use that file and the same for any other file I put in there.
I have absolutely no idea how I can accomplish this with mod_rewrite, I have played around with it for the best part of a few weeks to no avail, searched endlessly for possible solutions and have not made any progress.
Resolved the problem, seems that there was a looping problem that was breaking the rewrite.
##### Subdomain to subfolder
# Fix missing trailing slashes.
#RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$ [NC]
#RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
#RewriteCond %{DOCUMENT_ROOT}/%2%{REQUEST_URI}/ -d
#RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]
# Rewrite sub domains.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^(.*)$ /projects/%2/$1 [QSA,L]

using mod_rewrite on ajax site to load root index page when you access folders in url

I'm building an Ajax site that runs off of a root-level index.html file and uses history.js for pushState/popState, which I have updating the urls such that they are nice and clean without hashes or bangs (Example: site.com/section/1).
How can I do a mod_rewrite so that when a user tries to link to site.com/section/1 or site.com/section (or anywhere other than the root), the server serves up site.com/index.html?
From there the js would load the requested content in the url via ajax.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /index.html [L]
If you want to do something with the actual request (the /section/1 part) you can access it via $1. Example:
RewriteRule (.*) /index.html?path=$1 [L]
Which will rewrite /section/1 to /index.html?path=/section/1

Resources