How to mod rewrite this URL correctly? - .htaccess

I am adding a REST API to my application. The REST API is located at /api of my app. I want to route all requests correctly including requests that have parameters. I have the following htaccess rules which are working for the most part:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
</IfModule>
Using these rules, I can now go to:
mysite.com/api/projects/get and it will correctly give me back JSON data as if I would have accessed it the regular way mysite.com?url=api/projects/get
My problem begins when I try to add parameters to the request.
My application will already handle parameters. So if I were to go to: mysite.com/api/projects&type=1, it will give me back the projects of type 1. However, I think it is expected that the URL would look more like: mysite.com/api/projects?type=1 (note the ? instead of the &)
How would I modify my htaccess rules to handle this?
I was trying the following but with no luck:
RewriteRule ^(.*)/?(.*)$ index.php?url=$1&$2 [L]

You'll need to use the Query String Append flag, as shown below:
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Per the documentation:
When the replacement URI contains a query string, the default behavior
of RewriteRule is to discard the existing query string, and replace it
with the newly generated one. Using the [QSA] flag causes the query
strings to be combined.
Consider the following rule:
RewriteRule "/pages/(.+)" "/page.php?page=$1" [QSA]
With the [QSA] flag, a request for /pages/123?one=two will be mapped to
/page.php?page=123&one=two. Without the [QSA] flag, that same request
will be mapped to /page.php?page=123 - that is, the existing query
string will be discarded.

Related

Tricky .htaccess mod_rewrite syntax problem

I got stuck, and even reading through tons of forum posts didn't help me.
The challenge:
I need URIs to be rewritten and queries to be maintained
Examples 1:
example.com/test/23/result/7
shall be redirected to a script under
example.com/test/
That works quite well with an .htaccess entry like this:
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^test/(.+)$ test/?s=$1
The URI is displayed unaltered. The called script is called, and the additional subdirectory definitions can be retrieved in PHP either through variable $_GET['s'] or $_SERVER['REQUEST_URI']. All is fine so far. The problem starts when adding a query string:
Example 2:
example.com/test/23/result/7?id=16
shall be redirected to the same script under
example.com/test/?id=16
Even when I add [QSA] to the rewrite rule, the URI is not parsed correctly. I tried several ways to initiate a redirect. All failed. The redirect either points to a non-existing address or the query string gets lost. Besides the initial URI subdirectory information, here I would need the query string to be evaluated in my script. Both pieces of data need to be transferred to it.
Does anyone have a solution?
Thanks a lot for sharing your expertise!
I would go with following htaccess Rules. This assumes that you have index.php file which is taking care of non-existing pages request in later your Rules.
RewriteEngine ON
##Rules for handling index.php url here.
RewriteCond %{THE_REQUEST} \s/([^/]*)/.*\?index\.php\s [NC]
RewriteRule ^ %1?%{QUERY_STRING} [NC,L]
##Rules for non-existing pages here.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
###Rest of your rules go here.....

.htaccess rewrite request from OLD rest endpoint NEW endpoint

I am trying to include in my .htaccess file a condition to rewrite requests to a REST endpoint that will no longer exist after I perform some updates to the location of the new endpoint. The existing request looks something like this:
https://www.example.com/applications/interface/?info&key=xxx&indentifier=xxx
I would like the new request to be similar structure, just in a different location, in the community folder:
https://www.example.com/community/applications/interface/?info&key=xxx&indentifier=xxx
Any help would be greatly appreciated. My existing .htaccess looks like below:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.(js|css|jpeg|jpg|gif|png|ico|map)(\?|$) /404error.php [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Is there a reason why you can't just redirect the old request to the new one? Does the URI need to be internally rewritten?
If a redirect is good enough, you can do something like this (note that I'm using mod_rewrite and not mod_alias' Redirect directive, this is because they both end up getting applied to the same request and may conflict with your existing routing rule)
RewriteRule ^applications/interface/$ /community/applications/interface/ [L,R]
And you'd want that right under RewriteBase. This will take requests that look like /applications/interface/ and redirect them to /community/applications/interface/ with all of the query string parameters intact. The regex will only match that URI specifically, with the trailing / and as well.
If you need to do some sort of internal rewrite, I'd suggest doing this within your framework instead of trying to use mod_rewrite in the htaccess file. You've got it setup so every request is routed to index.php and it's up to that code to figure out what needs to go where.

How do I redirect a url with parameters

How do I redirect a url with parameters
I will like to write this url:
http://mydomain.com/dk/silkeborg?latitude=56.1631229&longitude=9.536976500000037&zoom=14
and redirect it to
http://mydomain.com/index.php?country=dk&city=silkeborg&latitude=56.1631229&longitude=9.536976500000037&zoom=14
To day I use the below rule, that don't take any parameters
RewriteRule (dk|de)/(.*) index.php?country=$1&city=$2 [NC]
Please help me
You do need to use [QSA] because you're rewriting the query (it's enabled by default unless you rewrite the query). Here we're capturing the country code and passing it as a var. Then QSA is catching the rest of the variables and adding them to the query string.
RewriteCond %{REQUEST_URI} ^/(dk|de)/ [NC]
RewriteRule .* index.php?country=%1 [QSA,L]
To use your existing rule, you would append [QSA]
RewriteRule (dk|de)/(.*) index.php?country=$1&city=$2 [QSA,NC,L]
When the page loads you can access the country via $_GET['country'] and city via $_GET['city'].

RewriteRule for the same file which is currently targeted

I have a file like
www.domain.com/test.php
I want to write a rule that when ever this is called i am sending an argument to this file but I don't want them to show in the URL I.E. when the above path is in the browser the actual rule should be:
www.domain.com/test.php?state=yes
What should be the .htaccess rule for this?
Currently i have in my .htaccess
RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
RewriteRule ^test\.php$ /test.php?view=index [NC,L]
But this is throwing a 500 server error???
I don't get a 500 error, what else do you have in your .htaccess?
Here's what you can use:
RewriteEngine on
RewriteBase /
RewriteRule ^test\.php test.php?view=index [NC,L,QSA]
The QSA flag was missing:
When the replacement URI contains a query string, the default behavior of RewriteRule is to discard the existing query string, and replace it with the newly generated one. Using the [QSA] flag causes the query strings to be combined.
Consider the following rule:
RewriteRule /pages/(.+) /page.php?page=$1 [QSA]
With the [QSA] flag, a request for /pages/123?one=two will be mapped to /page.php?page=123&one=two. Without the [QSA] flag, that same request will be mapped to /page.php?page=123 - that is, the existing query string will be discarded.
source: http://httpd.apache.org/docs/current/rewrite/flags.html#flag_qsa

Problems with url rewrite of query string

I'm trying to rewrite urls like http://www.url.com/blog/?p=123 to http://www.url.com/#blog/123. I've read up on things and found that you can only parse the query string in the RewriteCond so I tried something like:
RewriteCond %{QUERY_STRING} ^p=([0-9]*)$
RewriteRule ^.*$ /#blog/%0 [NE,R]
When I try this the urls end up being rewritten to:
http://www.url.com/#blog/p=213?p=213
Any ideas how to do this properly? Also, is there a way to add an additional RewriteCond that checks that the REQUEST_URI contains blog?
You can do this by removing the query string entirely:
RewriteCond %{QUERY_STRING} ^p=([0-9]*)$
RewriteRule ^.*$ /#blog/%1? [NE,R]
This should give you:
http://www.url.com/#blog/213
If you want to check if the URL contains the term "blog" then simply check:
RewriteCond %{REQUEST_URI} .*/blog/.*
It is important to note that you will not be able to check for "blog" in links like http://www.url.com/#blog because, as noted by Patrick, everything after the # is not sent to the server.
See the Apache wiki on mod_rewrite for more information.
That may not work because browsers do not send the fragment of the url after the hash (#) with the request, so any request for http://www.url.com/#blog/p=213?p=213 will be a request for http://www.url.com/
The hash fragment is supposed to be used for anchor tags on pages, and is never sent to the server.
Try this rule in your .htaccess file:
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteCond %{QUERY_STRING} ^p=(.*)$ [NC]
RewriteRule ^blog/?$ /#blog/%1? [NC,NE,L,R]
With above a URL of http://localhost/blog/?p=1234 will become http://localhost/#blog/1234

Resources