I am trying to get some help with this URL rewrite. I have already read multiple tutorials and documentation pages on how to do all this, but none of it makes sense to me. I also don't understand regular expression, so that doesn't help either. I have a semi working piece of code and just need help getting it working correctly.
I need: http://subdomain.domain.com?dl=2
to redirect to http://domain.com/subdomain.php?dl=2
The code I have is
RewriteEngine on
RewriteCond %{HTTP_HOST} ^subdomain.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !page.php
RewriteRule ^(.+/)?([^/]*)$ page.php?dl=$2 [QSA,L,NC]
Which sends the variable but can't figure out the subdomain part. If anyone could please help me out, it would be greatly appreciated.
You need to check the QUERY_STRING as RewriteRule doesn't include it. In addition, your rule is not using the redirect flag R.
RewriteEngine on
# First, check for the subdomain
RewriteCond %{HTTP_HOST} ^subdomain.domain.com$ [NC]
# Then, check the query string - it should match digits (\d+)
RewriteCond %{QUERY_STRING} ^dl=\d+ [NC]
# Check if we are not at subdomain.php
# (This is redundant, but leaving it here in case you really need it)
RewriteCond %{REQUEST_URI} !^/subdomain.php
# If all the above conditions are true, match a root-request
# and redirect to domain.com/subdomain.php with the query string
# Note: You don't need to actually specify the query string
# in the destination URI - Apache will automatically
# hand it over upon redirect (using the R flag).
# The only time this is not the case is when you
# either add the QSD flag, or append the destination
# URI with a question mark.
RewriteRule ^$ http://domain.com/subdomain.php [R=302,L]
The above will redirect http://subdomain.domain.com/?dl=2 to http://domain.com/subdomain.php?dl=2. If you would like to make the redirect permanent and cached by browsers and search engines, change 302 to 301.
Related
I am using .htaccess to redirect certain subfolders of my domain, to remove the question mark to improve my URLs.
Currently my URLs are like this:
www.example.com/post/?sometitle
I am trying to remove the question mark, so it is the following URL:
www.example.com/post/sometitle
Currently I have the following code in my .htaccess file:
RewriteCond %{THE_REQUEST} /post/?([^\s&]+) [NC]
RewriteRule ^ /post/%1 [R=302,L,NE]
i am using php GET parameters, i am attempting for when the browser visits example.com/post/sometitle that the page that is currently example.com/post/?sometitle is displayed
In that case you need to the opposite of what you are asking in your question: you need to internally rewrite (not externally "redirect") the request from example.com/post/sometitle to example.com/post/?sometitle.
However, you must have already changed all the URLs in your application to use the new URL format (without the query string). You shouldn't be using .htaccess alone for this.
I also assume that /post is a physical directory and that you are really serving index.php in that directory (mod_dir is issuing an internal subrequest to this file). So, instead of /post/?sometitle, it's really /post/index.php?sometitle?
For example:
RewriteEngine On
# Rewrite /post/sometitle to filesystem path
RewriteRule ^post/([\w-]+)$ /post/index.php?$1 [L]
So, now when you request /post/sometitle the request is internally rewritten and handled by /post/index.php?sometitle instead.
I have assumed that "sometitle" can consist of 1 or more of the characters a-z, A-Z, 0-9, _ and -. Hence the regex [\w-]+.
If this is a new site then you can stop there. However, if you are changing an existing URL structure that has already been indexed by search engines and linked to by external third parties then you'll need to redirect the old URLs to the new. (Just to reiterate, you must have already changed the URL in your application, otherwise users will experience repeated redirects as they navigate your site.)
To implement the redirect, you can add something like the following before the above rewrite:
# Redirect any "stray" requests to the old URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ([\w-]+)
RewriteRule ^post/$ /post/%1 [R=302,NE,QSD,L]
The check against the REDIRECT_STATUS environment variable is to ensure we only redirect "direct requests" and thus avoiding a redirect loop.
(Change to 301 only when tested as OK, to avoid caching issues.)
In Summary:
RewriteEngine On
# Redirect any "stray" requests to the old URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ([\w-]+)
RewriteRule ^post/$ /post/%1 [R=302,NE,QSD,L]
# Rewrite /post/sometitle to filesystem path
RewriteRule ^post/([\w-]+)$ /post/index.php?$1 [L]
UPDATE: If you have multiple URLs ("folders") that all follow the same pattern, such as /post/<title>, /home/<title> and /build/<title> then you can modify the above to cater for all three, for example:
# Redirect any "stray" requests to the old URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ([\w-]+)
RewriteRule ^(post|home|build)/$ /$1/%1 [R=302,NE,QSD,L]
# Rewrite /post/sometitle to filesystem path
RewriteRule ^(post|home|build)/([\w-]+)$ /$1/index.php?$2 [L]
Aside: (With my Webmasters hat on...) This is not really much of an "improvement" to the URL structure. If this is an established website with many backlinks and good SE ranking then you should think twice about making this change as you could see a dip in rankings at least initially.
If only changing from query is your requirement then try with below, we are using QSD flag to discard our query string after our rule matched.
RewriteCond %{QUERY_STRING} ([^\s&]+) [NC]
RewriteRule ^ /post/%1 [R=302,L,NE,QSD]
I have searched but cannot find a specific answer for this exact redirect style...
I have this structure of URL with this specific parameter:
https://websitename.com/directory/index.php?option=com_virtuemart&view=cart
I want it redirected to:
https://websitename.com/shopping-cart/
Note that the above mentioned "directory" changes, but the index.php with the parameters stay the same. No matter what the directory is, I always want it to go to the same exact redirect.
I cannot seem to get the right redirect working in htaccess. Can anyone help?
You can use this redirect rule as your first rule in site root .htaccess:
RewriteEngine On
RewriteCond %{THE_REQUEST} /(?:index\.php)?\?option=com_virtuemart&view=cart [NC]
RewriteRule ^ /shopping-cart/? [L,R=308]
# remaining rules go below this
You can use a set like this. It takes care on the param view=cart
RewriteCond %{QUERY_STRING} (^|&)view=cart
RewriteRule ^(.*)$ /shopping-cart/? [L,NC,R=301]
If you want to keep the querystring params, then change
/shopping-cart/?
to
/shopping-cart/
without questionmark
I have several URLs with question marks that need to be removed. For example, I need to redirect this URL:
http://example.net/?/services
To this URL:
http://example.net/services
I have many more like this, so I would like something that can catch everything with the question mark and properly redirect it. Many of the answers I found were trying to use QUERY_STRING as the condition for the rewrite, but without parameters this does not help. After some digging I found a RewiteCond that works, but the RewriteRule redirects to the homepage, rather than the URL without the question mark. What I have currently is this:
# Remove question mark from string
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?([^&\ ]+)
RewriteRule ^ /%1? [L,R=301]
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
The first block is the rewrite that I have so far, and the next two are for the CMS url routing. What seems to be happening is that my rewrite in the first block is not keeping the rest of the url. I have tried several combinations and can't seem to figure out how to keep the rest of the url intact.
Many of the answers I found were trying to use QUERY_STRING as the condition for the rewrite, but without parameters this does not help.
Yes, this is exactly what the first URL, with a question mark, contains. So, I'm not sure why "this does not help"? In the URL http://example.net/?/services, /services is the query string. Whether there are key/value pairs (ie. "parameters") is irrelevant.
To redirect URLs of the form http://example.net/?/services, that consist of no URL-path and only a query string, try something like:
# Remove question mark from string
RewriteCond %{QUERY_STRING} ^/(.+)
RewriteRule ^$ /%1? [R,L]
%1 is a backreference to the captured group in the last matched CondPattern (ie. (.+), which captures services). This assumes that the query string (after the ?) always starts with a slash, as in your example. (Incidentally, this is also what your front controller is doing, in reverse, so I assume it must be correct.)
The trailing ? on the substitution removes the original query string from the request.
Make sure you clear your browser cache, as any earlier/erroneous 301s will have been cached by the browser.
If this is intended to be a permanent (301) redirect then change R to R=301, but only when you are sure it's working OK.
I have problem when I try to redirect and rewrite together.
I have site example.com/show_table.php?table=12 (max 99 tables). I wanted nice links, so I got this .htacces rw rule:
RewriteRule ^table/([0-9]{1,2})$ show_table.php?table=$1 [L,NC]
Now are links something like example.com/table/12 - it's definitely OK. But I want all old links redirect to new format. So I use Redirect 301, I added to .htaccess this code:
RewriteCond %{REQUEST_URI} show_table.php
RewriteCond %{QUERY_STRING} ^table=([0-9]{1,2})$
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
But when I visit example.com/show_table.php?table=12, I receive just redir-loop. I don't understant - the first is rewrite, the second is redirection, there ain't no two redirections. Do You see any error?
Thanks!
Instead of checking REQUEST_URI in the condition, you need to be checking in THE_REQUEST (which contains the full original HTTP request, like GET /show_table.php HTTP/1.1). When Apache performs the rewrite, it changes REQUEST_URI, so to the rewritten value, and that sends you into a loop.
# Match show_table.php in the input request
RewriteCond %{THE_REQUEST} /show_table\.php
RewriteCond %{QUERY_STRING} ^table=([0-9]{1,2})$
# Do a full redirection to the new URL
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
# Then apply the internal rewrite as you already have working
RewriteRule ^table/([0-9]{1,2})$ show_table.php?table=$1 [L,NC]
You could get more specific in the %{THE_REQUEST} condition, but it should be sufficient and not harmful to use show_table\.php as the expression.
You'll want to read over the notes on THE_REQUEST over at Apache's RewriteCond documentation.
Note: Technically, you can capture the query string in the same RewriteCond and reduce it to just one condition. This is a little shorter:
# THE_REQUEST will include the query string so you can get it here.
RewriteCond %{THE_REQUEST} /show_table\.php\?table=([0-9]{1,2})
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
i have wildcard subdomains sets already and works fine, now i wish have friends url for the content in thats subdomains, the structure of my site is if the user type subdomain.maindomain.com and the .htaccess redirect to
blogs/index.php?user=subdomain
where blogs/index.php receive the param and show the correct content
now i try to make the url function like this
subdomain.maindoamin.com/24/title-of-content
and then .htaccess must result
blogs/index.php?id_content=24&title=title-of-content
i have the next .htaccess
Options +FollowSymLinks
#this force to server the content always without www.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$
RewriteRule ^(.*)$ http://%1/$1 [R=301]
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteRule ^(.*)$ blogs/index.php?url=%1 [QSA,L]
#the next line i can't make work to make nice url
RewriteRule ^/(.*)/(.*)$ blogs/index.php?idP=$1&name=$2 [L]
not working because when i make in index.php
echo $_SERVER['REQUEST_URI'];
don't show idP=24 show /24/title-of-content and i need $_GET(idP)
i really apreciate some light on this stuff i am not expert on htaccess, thanks in advance to everybody.
There are two problems:
The first argument of RewriteRule matches against everything after the slash of the directory .htaccess is in, and before the query string. If .htaccess is in your www-root, and you get the url http://www.example.com/shiny/unicorns.php?are=shiny, you match against shiny/unicorns.php. It will never start with a slash, so ^/ will never match.
Rules are executed in order. If you go to http://sub.example.com/10/unicorns, the second rule will match first and rewrite the request to /blogs/index.php?url=10/unicorns. If you removed the leading slash the third rule would match, but normally you wouldn't want that. You want to have the third rule only match
You want to move the third rule up so it is the second rule. You want to make it more specific to only match with subdomains. You also know the first part contains only numbers, so use that knowledge to prevent blogs/index.php from matching your now second rule. You also need to prevent blogs/index.php from matching the now third rule to prevent it from matching itself. Last but not least I removed [L] from the now second rule, since the third rule will match anyway.
#the next line i can't make work to make nice url
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^([0-9]+)/([^/]+)$ blogs/index.php?idP=$1&name=$2
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteCond %{REQUEST_URI} !/blogs/index\.php
RewriteRule ^ blogs/index.php?url=%1 [QSA,L]