Reputation: 223
I have seen a lot of answers to this, but for some reason none of them have worked for me. I have a form on a website that needs to POST data to a php file (which will then send a PHPMailer).
I want the website to have WWW forced and have the .php extensions removed from the URL. I have already made some changes to my .htaccess file whilst debugging this problem.
I've also noticed, that when I go to a page on my website, e.g. http://example.com.au/contact
, then WWW won't be forced to the start of the url. But if I go to http://example.com.au
(index), then it will change to http://www.example.com.au
. How can I change the .htaccess so that I can get all of the subpages to force WWW, along with not removing POST values?
My current .htaccess:
RewriteEngine on
# Remove .php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
# Force WWW
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L]
I originally had an R=301
tag with the [L]
of the second RewriteRule
, but apparently that was a cause of losing POST values, so I removed that. I have also tried both with and without
RewriteCond %{REQUEST_METHOD} !POST
before both, one of, and neither rules.
Here's a simplified version of my Form (without bootstrap classes, etc.):
<div class="form_container">
<form name="contactForm" id="contact_form" action="http://www.*MyURL*.com.au/scripts/contact_send" method="POST">
<div class="row">
<div>
<label for="inputFirstName">First Name: </label>
<input name="firstname" id="inputFirstName" type="text" required>
</div>
<div>
<label for="inputSurname">Surname: </label>
<input name="surname" id="inputSurname" type="text" required>
</div>
</div>
<div class="row">
<div>
<label for="inputEmail">Email: </label>
<input name="email" id="inputEmail" type="email" required>
</div>
<div>
<label for="inputPhone">Phone (optional): </label>
<input name="phone" id="inputPhone" type="tel">
</div>
</div>
<div class="row">
<div>
<input type="submit" name="submit" value="Send">
</div>
</div>
</form>
</div>
I have tried the form action, both with and without the .php extension, and both with and without the full URL, all returning empty arrays for var_dump($_POST)
.
All inputs in the form have both name
tags and id
tags.
jQuery (w/ validate) Script:
$('#contact_form').validate({
...
submitHandler: function(form){
$('.form_container').html('<div class="loader"></div>');
$('html, body').animate({scrollTop: $('#header').height()}, 500);
$.ajax({
url: form.action,
type: form.method,
data: $('#contact_form').serialize(),
success: function(data) {
$('.form_container').html(data);
}
});
}
});
The validator does work; the form won't submit with empty inputs.
For the purpose of debugging, I've changed contact_send.php
to this:
<?php
var_dump($_POST);
?>
I really hope that someone can help me, I'm losing my wits with this problem!
Thanks!
Upvotes: 0
Views: 3423
Reputation: 74028
As long as you only rewrite instead of R|redirect
, the URL shown in the browser won't change. However, a redirect status of 301
or 302
(default) will cause a change in the request method to GET
.
If you want to keep the method the same, you must use status codes 307
307 Temporary Redirect (since HTTP/1.1)
In this case, the request should be repeated with another URI; however, future requests should still use the original URI. In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the original request. For example, a POST request should be repeated using another POST request.
and 308
308 Permanent Redirect (RFC 7538)
The request and all future requests should be repeated using another URI. 307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change. So, for example, submitting a form to a permanently redirected resource may continue smoothly.
So instead of
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L]
you should use
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=307,L]
to keep the POST method.
I didn't look at the Javascript part first, examining it closer shows
$('.form_container').html('<div class="loader"></div>');
// ...
$.ajax({
// ...
data: $('#contact_form').serialize(),
// ...
});
The code first removes the form, and then tries to fetch the input values with serialize()
. Since the form isn't there anymore, no $_POST
data can be transmitted.
Maybe fetching the form data first, helps here, e.g.
var form_data = $('#contact_form').serialize();
$('.form_container').html('<div class="loader"></div>');
// ...
$.ajax({
// ...
data: form_data,
// ...
});
Upvotes: 2