I am working on a project in which url Rewriting was done. Here is the link of the old uri
http://www.mysite.pk/jobs/search/faisalabad/all-cats
But now in the new url I have changed it to
http://www.mysite.pk/jobs/pakistan/faisalabad/all-cats
what I want to do is to change the redirect all the url's whcih have http://www.mysite.pk/jobs/search/ search after job in them to the
http://www.mysite.pk/jobs/pakistan/
Here is my code of the route
$route["jobs/pakistan"]="vacancies/search";
I have also done
$route["search/pakistan"]="vacancies/search";
My .htaccess file content is
but it is not working
Kindly Helpe me
Thanks in advance
I think the problem are the missing placeholders. Without the placeholders your stated URL
http://www.mysite.pk/jobs/search/faisalabad/all-cats
won't match.
The correct route should look like this:
$route["jobs/pakistan/(:any)"]="vacancies/search";
$route["search/pakistan/(:any)"]="vacancies/search";
This way both jobs/pakistan and search/pakistan are working.
Edit
This RewriteRule will have the same effect when put in the .htaccess file.
RewriteRule ^jobs/search/(.*)?$ http://www.mysite.pk/jobs/pakistan/$1 [L,R=301]
Your .htaccess file then should look similar to this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Removes trailing slashes (prevents SEO duplicate content issues)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [L,R=301]
###
RewriteRule ^jobs/search/(.*)?$ http://www.mysite.pk/jobs/pakistan/$1 [L,R=301]
# Removes access to the system folder by users.
# Additionally this will allow you to create a System.php controller,
# previously this would not have been possible.
# 'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php/$1 [L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# Without mod_rewrite, route 404's to the front controller
ErrorDocument 404 /index.php
</IfModule>
The RewriteRule has following scheme:
RewriteRule [output] [original]
In this case when the "output" (url) starts with jobs/search/ (the ^ marks the beginning and $ the end) everything after this will be redirected to the original. The (.*) marks a reference for any content and will be inserted in the origin in place of $1. The [L,R=301] marks the type of the redirect (the HTTP response status code 301 means Moved Permanently), the L means that after the route is met, the following lines won't be processed.
Related
i am new to .htaccess usage and tried to learn through online resources but however i write it the rules negate each other and am having a hard time writing a good enough .htaccess file below is my current .htaccess file which works fine for some pages like removing extensions and rewriting subdomains please check below
## Flag for GoDaddy
Options +MultiViews
RewriteBase /
## Remove extensions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !=f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
## Redirect from extensions to non-extensions
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
## Redirect Pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=$1
RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps=$1 [L,QSA]
## Server Only
## Redirect from www - non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://$1/$1 [R=301,L]
## SSL Redirect
## RewriteEngine On
## RewriteCond %{HTTPS} ≠On
## RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
## Redirect non-existing pages to index.php
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Above is the .htaccess am currently using and i got it through tutorials from youtube it works good and redirects files.php to files only which am happy with but
as you can see above this line RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=$1 and the line below it are not passing through the ps but they show 404 page
i want the results to be domain.com/post-file-slug to go to exactly file domain.com/post-file.php?ps=post-slug-here for rule RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps=$1 [L,QSA]
and
domain.com/post/post-slug-here to go to exactly domain.com/post.php?ps=post-slug-here for rule
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=$1
I was working on this for 2 days now hopefully fix it soon. Thanks
## Flag for GoDaddy
Options +MultiViews
In what way is this a "flag for GoDaddy"? Enabling MultiViews will cause the ps URL parameter not to be passed to the post.php script. You need to ensure that MultiViews is disabled for the later rewrites to work as intended. ie.
Options -MultiViews
MultiViews (part of mod_negotiation) essentially enables extensionless URLs. It will result in a request for /post/post-slug-here to be "rewritten" to /post.php/post-slug-here before your mod_rewrite directive is processed, so it never matches and never rewrites the request to include the ps URL parameter.
## Remove extensions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !=f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
## Redirect from extensions to non-extensions
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
It is currently MultiViews that is allowing your extensionless URLs to work. The first condition (RewriteCond directive) above is incorrect. It should be !-f (not a file), not !=f (does not equal "f" - always true). However, this is still "wrong", as you need to check that the .php file exists before rewriting the request. If you simply rewrite all requests that do not map to a file (which is what you are trying to do here) then the later rewrites to post.php, post-files.php and index.php will not be processed as intended.
The regex \s/+(.+?)\.php[\s?] in the second condition is not strictly correct as it will result in a malformed redirect if .php occurs in the query string when it is omitted in the URL-path. eg. A request for /foo?bar.php would result in a redirect to /foo?bar when there should be no redirect at all in this instance. The regex needs to capture the URL-path only, so change the subpattern (.+?) to ([^?]+) instead.
These two rules are also the wrong way round. The external redirect should be first. As a general rule, external redirects should always go before internal rewrites.
It should be like this instead:
## Remove extensions
## Redirect to remove ".php" extension
RewriteCond %{THE_REQUEST} \s/+([^?]+?)\.php[\s?] [NC]
RewriteRule \.php$ /%1 [R=301,NE,L]
# Rewrite to append ".php" extension if corresponding ".php" file exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
You should already be linking to the file without the .php extension. The redirect to remove the .php extension is for SEO only when changing an existing URL structure.
No need to backslash-escape a literal dot when used inside a regex character class. The NC flag was superfluous here.
## Redirect Pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=$1
RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps=$1 [L,QSA]
RewriteCond directives only apply to the first RewriteRule directive that follows. So, the second rule above is processed unconditionally - is that the intention?
In fact, those two condition are probably superfluous. The regex would already appear to exclude actual files since the regex excludes dots. And do you need to be able to access filesystem directories directly?
The character class [a-zA-Z0-9-/] is "confusing". The last hyphen is seen as a literal hyphen (which is presumably the intention), but at first glance it can look like a range specifier (as used earlier in the character class). To avoid confusion when matching a literal hyphen inside a character class, either backslash-escape it, or move it to the first or last character in the character class. eg. [a-zA-Z0-9/-].
You are also missing the L flag from the first rule. (You've included it on the second.) Do you also need the QSA flag? (ie. Are you expecting additional URL parameters on the initial request?)
Having revised the "extension removal" rules above, this does not matter so much, but these rules that rewrite the request to post.php and post-files.php should really be above the "extension removal" rules.
## Redirect from www - non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://$1/$1 [R=301,L]
This rule is incorrect and in the wrong place. Canonical redirects (www to non-www and HTTP to HTTPS) should generally be above other rules. As mentioned above, redirects before rewrites.
But this rule is also wholly incorrect. $1 is a backreference to the first captured subpattern in the RewriteRule, so http://$1/$1 will naturally result in a malformed redirect. The first backreference should be %1 (to the last matched CondPattern) to match the requested hostname. Ordinarily, you should also be redirecting to HTTPS here, not HTTP. For example, the rule should read:
:
RewriteRule (.*) https://%1/$1 [R=301,L]
The ^ and $ surrounding the RewriteRule pattern are superfluous since regex is greedy by default.
## SSL Redirect
## RewriteEngine On
## RewriteCond %{HTTPS} ≠On
## RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Although commented out, it is also incorrect. It needs to go before the other rewrites. It should go at the top of the file if implementing HSTS or after the www to non-www redirect if not (and minimising the number of redirects).
The CondPattern in the preceding condition should be !on, not ≠On (which is wholly invalid on two counts... ≠ is not valid and the comparison is case-sensitive. HTTPS will always be lowercase.)
You are also missing the R=301 and L flags.
No need for a capturing group in the RewriteRule pattern, since this is not being used in the substitution string. ^ would suffice (and be more efficient) instead of (.*).
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
For readability, you should define your custom error documents at the top of the file. (Technically, it doesn't matter.)
## Redirect non-existing pages to index.php
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
For readability you should define the Options together at the top of the file (with -MultiViews). For example:
Options -MultiViews -Indexex +SymLinksIfOwnerMatch
(Disabling Indexes - auto-generated directory listings - is a good idea.)
You do not need to repeat the RewriteEngine directive. (Only the last instance of this directive does anything.) It is logical to place this rule near the top of the file, before your first mod_rewrite directive. (Although technically, the position of this directive in the file does not actually matter.)
Aside: You should be consistent in the prefix you use on your internal rewrites. On some rules you include the slash prefix (eg. /post.php), and on some you have omitted it (post-files.php). You have defined RewriteBase / (which isn't strictly required here as it happens) - RewriteBase only applies to relative substitution strings (ie. when the slash prefix is omitted).
UPDATE:
also i have file i want to exclude like 404.php in root directory from how do i exclude somefiles from the redirect. when i sent ajax to backend php file it redirected to homepage and failed to retrieve data.
To exclude specific files you would add a rule like the following, after the canonical redirects:
# Exclude "/404.php" from stripping the ".php" extension
RewriteRule ^404\.php$ - [L]
Generally, once you go extensionless for .php files you should be extensionless everywhere. So, there should be no unexpected redirects. The redirect is really only for SEO.
With regards to your AJAX requests, if you are making POST requests, then you could simply exclude all POST requests from further processing. For example:
# Prevent further processing of POST requests to ".php" files
RewriteCond %{REQUEST_METHOD} POST [NC]
RewriteRule \.php$ - [L]
Alternatively (or as well as), if your AJAX requests are setting a custom HTTP request header then you can check for this as well.
Summary
Bringing the above points together, it should look like this:
## Disable MultiViews and Indexes
Options -MultiViews -Indexes +SymLinksIfOwnerMatch
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
RewriteEngine On
RewriteBase /
#### Canonical redirects
## SSL Redirect
## RewriteCond %{HTTPS} !on
## RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
## Redirect from www - non-www
## >>> CHANGE TO "HTTPS://"
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule (.*) http://%1/$1 [R=301,L]
#### Rewrite Pages
RewriteRule ^post/([a-zA-Z0-9/-]+)$ post.php?ps=$1 [QSA,L]
RewriteRule ^([a-zA-Z0-9/-]+)$ post-files.php?ps=$1 [QSA,L]
#### Exceptions
## Exclude "/404.php" from stripping the ".php" extension
RewriteRule ^404\.php$ - [L]
## Prevent further processing of POST requests to ".php" files
RewriteCond %{REQUEST_METHOD} POST [NC]
RewriteRule \.php$ - [L]
#### Remove extensions
## Redirect to remove ".php" extension
RewriteCond %{THE_REQUEST} \s/+([^?]+)\.php[\s?] [NC]
RewriteRule \.php$ /%1 [R=301,NE,L]
## Rewrite to append ".php" extension if corresponding ".php" file exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
## Redirect non-existing pages to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
I got an old project and it has some bizarre issue. Its CodeIgniter project (version 2.X).
Google is indexing our URLs with index.php?. Below is an example
https://www.website.com/index.php?/my-seo-friendly-uri
I can see my pages from above url and with 2 more variants as below
https://www.website.com/index.php/my-seo-friendly-uri
https://www.website.com/my-seo-friendly-uri
We have used https://www.website.com/my-seo-friendly-uri throughout the site.
My question is how I can redirect https://www.website.com/index.php?/my-seo-friendly-uri and https://www.website.com/index.php/my-seo-friendly-uri to https://www.website.com/my-seo-friendly-uri?
The thing I already did
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^index.php/(.*)$ /$1 [R=302,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
This redirects index.php to normal URLs, but index.php? version of url is still not redirecting
In my config.php, I have the following settings
$config['index_page'] = '';
$config['uri_protocol'] = 'REQUEST_URI';
https://www.example.com/index.php?/my-seo-friendly-uri
This URL contains a query string and so requires a slightly different rule in order to match it. The RewriteRule pattern matches against the URL-path only (just index.php in this case). The query string is available in its own variable.
Add the following, before your existing directives (in addition to the directive that matches /index.php/my-seo-friendly-url - which is passed as path-info):
# Redirect URLs of the form "/index.php?/my-seo-friendly-uri"
# And "/?/my-seo-friendly-uri"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^(/.*)
RewriteRule ^(index\.php)?$ %1 [QSD,R=302,L]
The query string is captured (2nd condition), and the backreference (%1) is used to construct the redirect.
The first condition that checks against the REDIRECT_STATUS environment variable is required in order to prevent a redirect loop, since you appear to be using the query string method to route the codeigniter URLs in the later rewrite. The REDIRECT_STATUS env var is empty on the initial request, but set to "200" (as in 200 OK HTTP status) after the first successful rewrite.
The QSD flag (Apache 2.4+) is required to discard the original query string from the redirected request. If you are still on Apache 2.2 then append a ? (empty query string) to the substitution string instead. ie. %1?
By making the match for index.php optional (ie. ^(index\.php)?$) it will also canonicalise URLs that omit index.php, but still include the query string (that may or may not currently be a problem). eg. /?/my-seo-friendly-uri.
Note that this is currently a 302 (temporary) redirect (as is your existing redirect). Only change this to a 301 (permanent) redirect once you have confirmed it works OK. 301s are cached persistently by the browser so can make testing problematic.
Summary
Your .htaccess file should look like this:
RewriteEngine On
# Query string...
# Redirect URLs of the form "/index.php?/my-seo-friendly-uri"
# And "/?/my-seo-friendly-uri"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^(/.*)
RewriteRule ^(index\.php)?$ %1 [QSD,R=302,L]
# Path-Info...
# Redirect URLs of the form "/index.php/my-seo-friendly-uri"
# Also handles "/index.php" only
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index.php(?:/(.*))?$ /$1 [R=302,L]
# CodeIgniter Front-controller
# (NB: Using query string method to pass the URL)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?/$1 [L]
Additional notes...
The <IfModule> wrapper is not required.
(.*) is the same as ^(.*)$ since regex is greedy by default.
I've modified your existing path-info redirect (ie. /index.php/foo) to also redirect requests for /index.php only. This now requires an additional condition to avoid a redirect loop.
Your CodeIgniter front-controller is using the query string method to pass /my-seo-friendly-url to the backend (as used in the question). However, you have set $config['uri_protocol'] = 'REQUEST_URI'; - which contradicts with this (although shouldn't necessarily be a problem). However, if you are using the REQUEST_URI method then you can remove the ?/$1 part from the end of the final RewriteRule substitution string. For example:
For example, from this:
RewriteRule (.*) index.php?/$1 [L]
To this:
RewriteRule . index.php [L]
Use .htaccess................
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
<IfModule mod_php5.c>
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_php5.c>
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
</IfModule>
I have a url like this:
http://www.localhost.com/code_category/computers/
I want to change this url to:
http://www.localhost.com/category/computers/
I don't need url redirection.
My current htaccess file looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
You only want to redirect code_category to categoryexternally and keep the path as it is internally so, try this :
RewriteCond %{THE_REQUEST} !\s/+category/ [NC]
RewriteRule ^code_category/(.*)$ category/$1 [R=302,L,NE]
RewriteRule ^category/(.*)$ code_category/$1 [L]
The above will redirect any request containscode_category/whatever to category/whatever externally and keep the internal path as it is .
If you want only request contains code_category/computers/ change it to this :
RewriteCond %{THE_REQUEST} !\s/+category/computers/ [NC]
RewriteRule ^code_category/computers/(.*)$ category/computers/$1 [R=302,L,NE]
RewriteRule ^category/computers/(.*)$ code_category/computers/$1 [L]
test it , if it is fine change 302 to 301 for permanent redirection.
Note: clear your browser cache then test it.
.htaccess file
Add this code
RewriteEngine on
RewriteCond %{HTTP_HOST} ^localhost.com [NC,OR]
# without redirect
# RewriteRule ^/code_category/computers/$ category/computers/
RewriteRule ^/category/computers/$ code_category/computers/
# redirect method
# RedirectMatch 301 ^/code_category/computers/$ category/computers/
RewriteEngine On enables mod_rewrite.
RewriteCond %{HTTP_HOST} shows which URLs we do and don't want to run through the rewrite.
In this case, we want to match example.com.
! means "not." We don't want to rewrite a URL that already includes folder1, because then it would keep getting folder1 added, and it would become an infinitely long URL.
[NC] matches both upper- and lower-case versions of the URL.
RewriteRule defines a particular rule.
The first string of characters after RewriteRule defines what the original URL looks like. There's a more detailed explanation of the special characters at the end of this article.
The second string after RewriteRule defines the new URL. This is in relation to the document root (html) directory. / means the html directory itself, and subfolders can also be specified.
For Reference click here
Hope this helps!
I'm using codeigniter and have been able to use url's without "index.php" in there, but if I manually type in "index.php", the urls still work. I'd like to disable access to "index.php/controller" type urls in order to avoid duplicate content penalty from Google.
Here is what my current .htaccess file looks like:
Options +FollowSymLinks
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
You can try this by replacing the last 3 lines with this
RewriteCond $1 !^(index\.php|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
or maybe simply by removing the last line of your .htaccess.
Also you might need to change your /config/config.php to
$config['index_page'] = “”
The CI manual already gives you an (working) example on how to do it:
You can easily remove this file by using a .htaccess file with some
simple rules. Here is an example of
such a file, using the "negative"
method in which everything is
redirected except the specified items:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
In the above example, any HTTP request other than those for
index.php, images, and robots.txt is
treated as a request for your
index.php file.
Always be sure to check the manual first. It is really good and gives you an easy answer most of the time.
http://localhost/frontend_dev.php/1
Why is the above request redirected to frontend_dev.php instead of index.php?
I've read the .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
# uncomment the following line, if you are having trouble
# getting no_script_name to work
#RewriteBase /
# we skip all files with .something
#RewriteCond %{REQUEST_URI} \..+$
#RewriteCond %{REQUEST_URI} !\.html$
#RewriteRule .* - [L]
# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
If I'm understanding it correctly,if the requested file doesn't exist,it should be redirected to index.php,how can frontend_dev.php be run in the case above?
You have specified http://localhost/frontend_dev.php/1 as the URL - Apache simply serves up frontend_dev.php as you are explicitly asking for that file in the URL. Change your URL to http://localhost/index.php/1 to see the production controller.
The rewrite rules deal only with URLs that don't mention a front controller at all, ie. http://localhost/1 - the rewrite rules are not being parsed at all for the URL you initially provided, as Apache detected the frontend_dev.php file and found no matching rewrite rule to parse.
Simple. Because frontend_dev.php does exist, it is executed. And no redirect is performed.