I am lost after digging into this matter for a lot of days. We have the following redirects:
RewriteRule ^something/something2/?$ http://test.com/blabla?key=blablabla1287963%3D [R=301,L,E=OUTLINK:1]
Header always set X-Robots-Tag "noindex" env=OUTLINK
Unfortunately that %3D got stripped by the module (mod_rewrite). The main problem is that I know how to manually fix it but I have multiple similar redirects and I need a "global solution". Please note that moving back to redirect 301 (I had no issues with redirect 301 and encoded URLs/characters) is not an option since I want to use noindex...
Thank you!
that %3D got stripped by the module
I think you'll find that it's the %3 that gets stripped, not %3D. %3 is seen as a backreference to a preceding condition - which I suspect doesn't exist - so gets replaced with an empty string in the substitution. (This would not have been a problem with Redirect since %N backreferences aren't a thing with mod_alias.)
You need to backslash escape the % to represent a literal % in the substitution string in order to negate its special meaning in this case.
You will then need the NE flag on the RewriteRule to prevent the % itself from being URL encoded (as %25) in the response (essentially doubly encoding the URL param value).
For example:
RewriteRule ^foo$ http://test.com/blabla?key=blablabla1287961\%3D [NE,R=302,L,E=OUTLINK:1]
I have multiple similar redirects and I need a "global solution"
As far as a "global solution" goes, there isn't a magic switch you can enable on the server that will "fix" this. You need to modify each directive where this conflict occurs.
I'm working on a website in which I have a folder structure that is organized but creates a long and not "Pretty URL". What I was wondering how would I accomplish a URL Routing/Rewrite from say:
https://DOMIAN.NAME/resources/views/back-end/FILENAME.php
to simply
https://DOMAIN.NAME/FILENAME (no extension)
Is this possible? Would it be .htaccess rewrite or PHP or something else? Also through the same way how would I make it so that if some one types http it will direct them to same URL but with https?
Thanks :)
Fixed!
I'm not sure if I missed type or something but I was able to get the code to work in which was listed on Digital Ocean's blog! I thought I used the same code but must have; like mentioned, typed something wrong or used a completely different code!
The Article
The Code:
RewriteEngine On
RewriteRule ^FILENAME$ /resources/views/back-end/FILENAME.php [NC]
Which is basically doing:
RewriteRule = The rule statement
^ = Looks/keeps the information before the "NEW" variable
FILENAME = The "NEW" variable / or page URI
$ = Includes whatever else is in the URL
resources/views/back-end/FILENAME.php = The "OLD" variable or current URI / file path
[NC] = Allows for the variables to be types in any case types such as "filename", "FILENAME", "FileName", etc.
I really had troubles making a title. So if you have something better, please edit it.
Now to the question:
I'm trying to rewrite some URL's with mod_rewrite in my .htaccess file.
So, what I'm trying to do is to make 2 of the same queries, which of course won't work. Only for one of the rules. So I was thinking if there's some way to tell that if the first rule fails go to the next one? Or - if a rule fails keep looking for another?
Those are my rules which is identical except for the last parameter.
RewriteRule ^udforsk/([a-z-]+)/([0-9]+)$ index.php?page=udforsk&q=1&s=$1&val=$2
RewriteRule ^udforsk/([a-z-]+)/([0-9]+)$ index.php?page=udforsk&q=1&s=$1&p=$2
Correct me if I'm wrong but, if you are passing the arguments in via GET, then index.php should handle the error that would happen if it were missing a GET variable.
In index.php, treat $_GET["p"] like you would treat $_GET["val"], actually, why not use isset() and set p equal to val (if p isn't already set)
The rewrite won't check to see if the page you are calling in your rule is actually valid. It will just try to serve it up and then because you don't have [L] it will try to serve up the next one too.
What you should probably do is change your first URL to pass that $2 value as two different parameters
RewriteRule ^udforsk/([a-z-]+)/([0-9]+)$ index.php?page=udforsk&q=1&s=$1&val=$2
RewriteRule ^udforsk/([a-z-]+)/([0-9]+)$ index.php?page=udforsk&q=1&s=$1&p=$2
should be
RewriteRule ^udforsk/([a-z-]+)/([0-9]+)$ index.php?page=udforsk&q=1&s=$1&val=$2&p=$2
Then let your index.php do the work of picking which parm to use "val" or "p" based on logic in the php script.
For sure in your php code use "isset" to test for the variable.
$value = (isset($_REQUEST["val"]) ? $_REQUEST["val"] : (isset($_REQUEST["p"]) ? $_REQUEST["p"] : "error"));
$value will hold the contents of "val" or "p" or the word "error" if neither of the others are set.
About the system
I have URLs of this format in my project:-
http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0
Where keyword/class pair means search with "class" keyword.
I have a common index.php file which executes for every module in the project. There is only a rewrite rule to remove the index.php from URL:-
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
I am using urlencode() while preparing the search URL and urldecode() while reading the search URL.
Problem
Only the forward slash character is breaking URLs causing 404 page not found error.
For example, if I search one/two the URL is
http://project_name/browse_by_exam/type/tutor_search/keyword/one%2Ftwo/new_search/1/search_exam/0/search_subject/0/page_sort/
How do I fix this? I need to keep index.php hidden in the URL. Otherwise, if that was not needed, there would have been no problem with forward slash and I could have used this URL:-
http://project_name/index.php?browse_by_exam/type/tutor_search/keyword/one
%2Ftwo/new_search/1/search_exam/0/search_subject/0
Apache denies all URLs with %2F in the path part, for security reasons: scripts can't normally (ie. without rewriting) tell the difference between %2F and / due to the PATH_INFO environment variable being automatically URL-decoded (which is stupid, but a long-standing part of the CGI specification so there's nothing can be done about it).
You can turn this feature off using the AllowEncodedSlashes directive, but note that other web servers will still disallow it (with no option to turn that off), and that other characters may also be taboo (eg. %5C), and that %00 in particular will always be blocked by both Apache and IIS. So if your application relied on being able to have %2F or other characters in a path part you'd be limiting your compatibility/deployment options.
I am using urlencode() while preparing the search URL
You should use rawurlencode(), not urlencode() for escaping path parts. urlencode() is misnamed, it is actually for application/x-www-form-urlencoded data such as in the query string or the body of a POST request, and not for other parts of the URL.
The difference is that + doesn't mean space in path parts. rawurlencode() will correctly produce %20 instead, which will work both in form-encoded data and other parts of the URL.
Replace %2F with %252F after url encoding
PHP
function custom_http_build_query($query=array()){
return str_replace('%2F','%252F', http_build_query($query));
}
Handle the request via htaccess
.htaccess
RewriteCond %{REQUEST_URI} ^(.*?)(%252F)(.*?)$ [NC]
RewriteRule . %1/%3 [R=301,L,NE]
Resources
http://www.leakon.com/archives/865
In Apache, AllowEncodedSlashes On would prevent the request from being immediately rejected with a 404.
Just another idea on how to fix this.
$encoded_url = str_replace('%2F', '/', urlencode($url));
I had the same problem with slash in url get param, in my case following php code works:
$value = "hello/world"
$value = str_replace('/', '/', $value;?>
$value = urlencode($value);?>
# $value is now hello%26%2347%3Bworld
I first replace the slash by html entity and then I do the url encoding.
Here's my humble opinion. !!!! Don't !!!! change settings on the server to make your parameters work correctly. This is a time bomb waiting to happen someday when you change servers.
The best way I have found is to just convert the parameter to base 64 encoding. So in my case, I'm calling a php service from Angular and passing a parameter that could contain any value.
So my typescript code in the client looks like this:
private encodeParameter(parm:string){
if (!parm){
return null;
}
return btoa(parm);
}
And to retrieve the parameter in php:
$item_name = $request->getAttribute('item_name');
$item_name = base64_decode($item_name);
On my hosting account this problem was caused by a ModSecurity rule that was set for all accounts automatically. Upon my reporting this problem, their admin quickly removed this rule for my account.
Use a different character and replace the slashes server side
e.g. Drupal.org uses %21 (the excalamation mark character !) to represent the slash in a url parameter.
Both of the links below work:
https://api.drupal.org/api/drupal/includes%21common.inc/7
https://api.drupal.org/api/drupal/includes!common.inc/7
If you're worried that the character may clash with a character in the parameter then use a combination of characters.
So your url would be
http://project_name/browse_by_exam/type/tutor_search/keyword/one_-!two/new_search/1/search_exam/0/search_subject/0
change it out with js and convert it back to a slash server side.
is simple for me use base64_encode
$term = base64_encode($term)
$url = $youurl.'?term='.$term
after you decode the term
$term = base64_decode($['GET']['term'])
this way encode the "/" and "\"
A standard solution for this problem is to allow slashes by making the parameter that may contain slashes the last parameter in the url.
For a product code url you would then have...
mysite.com/product/details/PR12345/22
For a search term you'd have
http://project/search_exam/0/search_subject/0/keyword/Psychology/Management
(The keyword here is Psychology/Management)
It's not a massive amount of work to process the first "named" parameters then concat the remaining ones to be product code or keyword.
Some frameworks have this facility built in to their routing definitions.
This is not applicable to use case involving two parameters that my contain slashes.
I use javascript encodeURI() function for the URL part that has forward slashes that should be seen as characters instead of http address.
Eg:
"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition")
see http://www.w3schools.com/tags/ref_urlencode.asp
I solved this by using 2 custom functions like so:
function slash_replace($query){
return str_replace('/','_', $query);
}
function slash_unreplace($query){
return str_replace('_','/', $query);
}
So to encode I could call:
rawurlencode(slash_replace($param))
and to decode I could call
slash_unreplace(rawurldecode($param);
Cheers!
You can use %2F if using it this way:
?param1=value1¶m2=value%2Fvalue
but if you use /param1=value1/param2=value%2Fvalue it will throw an error.
I am using htaccess. I try to pass a value in url like 'C++'.
like "http://domain.com/Details/c++/detail.html"
I am retrieving the value in htaccess like
RewriteRule ^Details/([a-zA-Z_0-9_.,'&/-]+)/(([a-zA-Z_0-9_.,'&/-]+).html)$ index.php?page=$2&id=$1
But it returns only 'c'. Symbol '+' not accepted. I need the the value 'c++'.
Is there any solution?
Try Url encoding the + character.
"http://domain.com/Details/c%25%25/detail.html"
Is it possible to escape it, like http://domain.com/Details/c%25%25/detail.html. (I'm only guessing)
http://domain.com/Details/c%2B%2B/detail.html
A small consolation is: you are not alone. Since this problem is by design in URIs, eben big sites like Google have their problems with it:
http://www.google.com/search?q=c++
This does a search for just ācā.
Try it with the B flag:
RewriteRule ^Details/([a-zA-Z0-9_.,'&/-]+)/([a-zA-Z0-9_.,'&/-]+\.html)$ index.php?page=$2&id=$1 [B]