I've tried every solution I could google, but I can't read the data from a POST array in my external PHP file. Here's the HTML of the text field.
<form>
<textarea id="comment_text_area" name="comments" rows="5" cols="40">
</textarea>
<label for="comment_text_area">Comment:</label>
<br>
<input type="submit" name="submit" value="Submit" onclick="SaveComments()">
</form>
... and the JS function making the AJAX call
function save()
{
var data = document.getElementById("comment_text_area");
var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xhr.open('POST', 'save_comments.php', true);
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
alert("Comments saved!");
}
}
xhr.send(data);
}
... and the PHP file
<?php
if(isset($_POST['comments']))
{
$data = htmlentities($_POST['comments']);
$file = "comments.txt";
file_put_contents($file, $data, FILE_APPEND | LOCK_EX);
}
else
{
$data = "empty";
$file = "comments.txt";
file_put_contents($file, $data, FILE_APPEND | LOCK_EX);
}
?>
What I know is working:
The AJAX call is completing successfully, and the script is being run and "empty" is being written.
Things I have tried:
I read that event listener functions should be attached to HTML elements before they are made, which seems counter-intuitive. Made no change.
Using
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
Didn't work. And, based on the research I've done for that, shouldn't that only seem necessary for GET calls? (I need to use POST)
Making the POST call synchronous. Nothing changed.
I Know that the name of the element you're passing needs to be what you rely on in the PHP script, but it's not working. I don't want to set form action="" because I don't want redirection, which is why I'm going through AJAX.
Finally, something I've noticed, it's changing the URL as I click submit, something I would expect from GET. That is GET specific, right? I clearly marked it as POST though.
Does anyone see what I am doing wrong?
P.S. - Please, if it's on the JS side of things, no jQuery. I've avoided it thus far, I'm trying to keep it that way.
You need a variable to pass in the request not just the value as
xhr.send("comments="+data);
So that in server side you can retrieve the data by param name.
Related
This is an update to a previous question marked as a duplicate (How do I send an AJAX POST request with parameters to PHP?)
I am sending an AJAX request to a PHP backend.
The Javascript functions to make and receive the request:
var httpRequest;
function makeRequest(){
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = receiveResponse;
httpRequest.open("POST", "ajax_handler.php", true);
httpRequest.setRequestHeader('Content-Type', 'application/json');
httpRequest.send(JSON.stringify({key:"value"}));
}
function receiveResponse() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
}
}
}
The PHP backend ajax_handler.php to process the request:
<?php
$data = file_get_contents('php://input');
echo $data;
?>
My original post was marked as a duplicate of this question. That page has no clear examples, though I was able to infer that I should use file_get_contents('php://input') instead of $_POST in the PHP backend, as shown.
Using the code shown, console.log(httpRequest.responseText) in the receiving function logs {"key":"value"} to the console. If I try to interpret this as an array in the PHP backend, however, with
<?php
$data = file_get_contents('php://input');
echo $data["key"];
?>
the response logs { to the console instead of the expected value.
In addition to the use of 'php://input', several responses in the linked duplicate also use the json_decode() function in the PHP backend.
If I include this function in the backend, however, as
<?php
$data = json_decode(file_get_contents('php://input'));
echo $data;
?>
The entire AJAX call breaks. It was set to trigger on a window click, but after including json_decode(), nothing happens on a window click, nothing is returned from the call, and nothing is logged to the console.
Without an example, it's hard for me to tell if I'm doing the AJAX cycle wrong, or if there's a different problem somewhere else in my code. So please, for the love of all that is holy, will someone please post or link me to a self-contained example showing how to make, process, and receive an AJAX call with parameters to a PHP backend? It's incomprehensible that this doesn't already exists somewhere on the internet, but I've been searching and asking for days, and I can't find a single example anywhere. This is without jQuery.
Thank you in advance.
Create an mcve and debug this piece by piece.
<?php
$data = json_decode('{ "test": 123 }');
echo $data;
Will output:
Recoverable fatal error: Object of class stdClass could not be converted to string in /...../test.php on line 4
You've got an object representing the data decoded from JSON. You need to echo a useful part of it. e.g.
<?php
$data = json_decode('{ "test": 123 }');
echo $data->test;
Hello friends i want use ajax on same php page. But problem is i can use ajax on different pages but not in same page. I saw people accomplished it with jquery but i dont wanna use jquery. Thanks-
<?php
$gg = $_POST['day'];
echo 'today is '.$gg;
?>
<html>
<head>
<script>
function clickMe(){
// Create our XMLHttpRequest object
var req = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
var url = "example.php";
var dayName = document.getElementById("dayName").innerText;
var vars = "day="+dayName;
req.open("POST", url, true);
// Set content type header information for sending url encoded variables in the request
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Access the onreadystatechange event for the XMLHttpRequest object
req.onreadystatechange = function() {
if(req.readyState == 4 && req.status == 200) {
let return_data = req.responseText;
document.getElementById("status").innerHTML = return_data;
}
}
// Send the data to PHP now... and wait for response to update the status div
req.send(vars); // Actually execute the request
</script>
</head>
<body>
<h2>Ajax Post to PHP and Get Return Data</h2>
<p id="dayName">saturday</p>
<button onclick="clickMe()">btn</button>
<br><br>
<div id="status"></div>
</body>
</html>
First of all in your php code you are getting input via $_GET and in your code you are sending a POST request which is counter intuitive. What you can do is when certain parameters are passed either through query string or request body with a post request, you can write your desired output and call die() to not display the rest of it which will interfere with the response you get. I don't see a real reason to do so in the same file but, here's an example using query string:
<?php
if(isset($_GET['day'])) {
die('Today is ' . htmlspecialchars($_GET['day']));
}
?>
Then in your javascript code make sure you send a valid request according to your needs.
It's not a good idea to use the same page to print html and do some php stuff. But, if you really want to do so, with javascript you can send another var like ajax=1 and change you php code :
<?php
if(isset($_POST['ajax'])) {
echo 'today is '.$_POST['day'];
exit;
}
?>
Answered
OK so I have it working now. Thanks to #ASK for the assist. There was just a few changes that needed to be made. A helpful resource for anyone else struggling with this was Using FormData Objects - MDN
My first mistake came from a misunderstanding of what e.preventDefault() was doing. I thought it just stopped the page from redirecting to processForm.php. In fact it does, but also stops the form from submitting to processForm.php too. So when I was making my ajax call to processForm.php the reason my $email variable wasn't returning the submitted email was because there had been no submitted email yet. And when I turned of e.preventDefault() it worked for the opposite reason. Quite obvious in hindsight.
I've posted my working changes at the bottom here. I'm not sure why but I had to leave out xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); to get it working. So I still need to learn more about setRequestHeader to know what's going on there.
Original Question:
So I've got this form that I send to processForm.php when submitted. I haven't got around to it yet but once sent, processForm.php will add the email to a database that will be used to serve a mailing list for a newsletter. Also note processForm.php will be used for another more complex contact form later.
What I'm trying to do right now is create the response message for the user.
After the user submits the form and the response from processForm.php is received a <div> will slide down from top of screen with the message, as shown in the below php.
I'm using JS (NO jQuery) to prevent the page redirect and AJAX to make the call to processForm.php. I get the responseText from processForm.php, but the $email is missing.
In the js if I comment out e.preventDefault();, allowing the page to redirect, $email is included in the echo $response. But with e.preventDefault(); engaged it isn't.
I've tried heaps of different variations of the code below, including just echoing $email, placing $email inside the $message variable but nothing works. The email is always excluded from the xhr.responseText.
Here's 2 screen shots of what's happening:
1) This image is with e.preventDefault(); called. (i.e. using ajax)
2) And here we see the response when e.preventDefault(); is commented out. (i.e. no ajax and redirected to processForm.php)
Since I still receive the echoed $response when making the ajax call I know processForm.php is building its variables and running the if statement. But why isn't $email included in the xhr.responseText?
The other variables, $message and $response are returned so what's going on?
Am I using $email = $_POST['email']; correctly? I think yes as it works with the redirect to processForm.php.
Here's the code.
I know their are security steps like htmlspecialchars and trim that should be used, but right now I just want to get it up and running.
HTML:
<form id="mailing_list_form" action="processForm.php" method="post" accept-charset="UTF-8">
<div id="their_email" class="their_email form_field">
<label for="email">Email</label>
<input id="email" type="email" name="email" required>
</div>
<div class="state_container form_field">
<label for="state">State</label>
<select name="state">
<option value="" disabled selected></option>
<option value="NSW">NSW</option>
<option value="Queensland">Queensland</option>
<option value="SA">SA</option>
<option value="Tasmaina">Tasmaina</option>
<option value="Victoria">Victoria</option>
<option value="WA">WA</option>
</select>
</div>
<button id="form_trigger" type="submit" name="mList">Subscribe</button>
</form>
PHP:
<?php
$mailingListForm = $_POST['mList'];
$email = $_POST['email'];
$state = $_POST['state'];
if(isset($mailingListForm)){
$message = "has been added to the mailing list.";
$response = '<h2 class="form_submitted_status">Succes!<i class="form_submitted_details">'.$email." ".$message.'</i></h2>';
echo $response;
}
?>
JS:
formTriggerClick();
function formTriggerClick(){
var formTrigger = document.getElementById("form_trigger");
formTrigger.addEventListener("click", function(event){
event.preventDefault();
if(formTrigger.hasAttribute("data-validation")){
processForm();
function processForm(){
getResponse(function(result){
var resultText = result;
var response = document.getElementsByClassName("form_submitted")[0];
response.innerHTML = resultText;
response.setAttribute("data-show", "response");
});
}// processForm() -- END --//
function getResponse(callback){
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
if(xhr.status === 200) {
callback(xhr.responseText);
}
}
};
xhr.open("POST", "processForm.php");
xhr.send();
}//getResponse() -- END --//
}// if formTrigger has data-validation -- END --//
});
}//formTriggerClick() // -- END --//
How is was solved:
All I had to do was:
1) create this var form to hold the filled out form.
2) and initiate a new FormData object inside send().
3) you'll note the setRequestHeader is commented out, I don't seem to need it.
3.1) Still working out why...
function getResponse(callback){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
if(xhr.status === 200) {
callback(xhr.responseText);
}
}
};
var form = document.getElementById("mailing_list_form");
xhr.open("POST", "processForm.php");
//xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(new FormData(form));
}//getResponse() -- END --//
And that's it. It all really boiled down to a misunderstanding of e.preventDefault(). And that I had used ajax previously to return a page and didn't need any of this (but that was because I was just returning the page/doc as is and not trying to construct variable values out of dynamic, submitted data)
Thanks to #ASK again for setting me straight.
I'm surprised that your form is submmiting.
I think your problem is this:
You are using form_trigger in the function formTriggerClick in line 1
And as far as I know you don't have element with id form_trigger instead you have trigger
You full working solution will be like this:
formTriggerClick();
function formTriggerClick(){
var formTrigger = document.getElementById("trigger");
...
Edit 1
Next problem you never send the value to the proccessForm.php.
Here is how you do something like that:
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("field1Name=value1&field2Name=value2&...");
See this for more details about AJAX http://www.w3schools.com/ajax/default.asp
Edit 2
And you initialize xhr like this:
var xhr = new XMLHttpRequest();
Edit 3
Heres how you send the data(However works for IE 10 and above):
var form = document.getElementById("formId");
var data = new FormData(form);
xrh.send(data);
For IE < 10:
var emailValue= document.getElementById("emailFieldId").value;
....
var data="email="+emailValue+"...so on";
xhr.send(data);
Here's a good example.
You could always use some functions. And that's when jQuery is very handy.
I have been researching on how to make an Ajax request and came up with this:
function ajax_post(){
// Create our XMLHttpRequest object
var xmlhttp = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
var url = "http://localhost:888...-files/test.php";
// Set content type header information for sending url encoded variables in the request
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Access the onreadystatechange event for the XMLHttpRequest object
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var return_data = xmlhttp.responseText;
document.getElementById("demo").innerHTML = return_data;
}
}
xmlhttp.open("POST", url, true);
xmlhttp.send(); // Actually execute the request
document.getElementById("demo").innerHTML = "processing...";
}
I saved this script as a file under: http://localhost:888...ascript/test.js <-- I have tested other scripts saved at this location and they work perfectly fine. My php file contains the following data (it is named "test.php"):
<?php
echo(rand(10,100));
?>
After I make the request to the php file which should display a random number according to the php code, my html looks like this:
<div style="display:none;">
<body onload="ajax_post()"> <------ Here you can see that I have called the function which executes the AJAX Request after the page has loaded.
<script type="text/javascript" src="http://localhost:888...ascript/test.js"></script>
</body>
</div>
<div id="demo"></div>
I keep refreshing the page and nothing appears. Does it have to do with my php code? Perhaps my Ajax request is wrongly structured? In terms of Ajax request, I have tried "GET" and "POST" as well and still nothing happens. I am new at Ajax and the might syntax my not make sense... Thank you in advance for the support.
Regards!!
I added some html to the php file and everything loads except the php file (php appeared as a comment). Then, I came up with the idea to compare the php file I created with the other php files on my local server. I identified a little difference. The other php files do not close the php, i.e. <?php echo 'Hello World'; without putting ?> at the end, and now it works. My php file looks like this:
<?php
echo 'Hello World';
I also simplified my script, making my structure look like follows:
<div id="demo"><div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready( function() {
$('#demo').load('http://localhost:8888/...php-files/test.php');
});
</script>
I used JQuery .load() property as it is simpler than the normal script (same principle).
I have a js file. Is it possible to do inside the js file a php coding? On my header I include my js file like this.
<script type="text/javascript" src="js/playthis.js"></script>
now inside my jsfile:
function getURL(e) {
alert(e+' javascript varibale');
<?php $url; ?> = e;
alert('<?php echo $url; ?>'+' php variable');
}
in my php file
<?php $url = "www.google.com"; ?>
<a href="#" onclick="getURL('<?php print $url; ?>');" class="title">
It's not working. Is there something wrong?
you have to make a new object for Ajax transaction named XMLHTTP REQUEST in some browsers and in I.E this is ActiveXObject basically; and this object belong to window object;
so the first step is:
if ( window.XMLHttpRequest ) {
XHR = new XMLHttpRequest();
}
else if ( window.ActiveXObject ) {
XHR = new ActiveXObject("Microsoft.XMLHTTP");
}
else {
alert("You Cant see because Your Browser Don't Support Ajax!!!\n Change Your Browser To A Modern One");
}
now, you have the right object
in next step, there is some methods for XHR object for send and receive you should know:
1/ onreadystatechange
2/readyState
3/status
4/open
5/send
6/setRequestHeader
first open a connection with open:
XHR.open("POST", url, true);
as you know, post is method of sending, and now you have to set the url you want to information send to, for example if you want to send the variable to the test.php, then the url is test.php...
true means the request will sent asynchronously..
next is set your request header, because your are using post method, in get method you don't need this:
XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
next is sending the request with send method with this format send(name, value):
XHR.send('value=' + value);
first string 'value=' is the index of $_POST that you will get in php, so in your php code, you'll give this with $_POST['value'], if you set the name to 'name=', in php you have $_POST['name'], be careful that in Ajax send param you have to use = after the name of data, but in php the = is not used...
after you sent the request; it's time to mange response:
XHR.onreadystatechange = function() {
if ( XHR.readyState == 4 && XHR.status == 200 ) {
document.getElementById('your target element for show result').innerHTML == XHR.responseText;
}
}
XHR.readyState == 4 and XHR.status == 200 means every thing is O.K.
this is the basics of Ajax as you wished for; but there is so many information for Ajax, and either you can use jQuery Ajax method that is so simple and flexible; But as you want I described the basics for you...
No it's not possible to have PHP code inside JS file.
You can make $.ajax call to a PHP file and that file can handle the setting of the variable required.
Hope this helps.
There are a few ways to handle this.
1 - Have .js files parsed by php. You will need to change your webserver configuration to do this.
2 - Use AJAX to interact with php.
3 - Have php render an additional JS snippet in the body onload event that sets this JS parameter (but still have the library as a seperate file).
this is not necessary, when you print the url with print $url in onclick attribute inside the php page as an argument for getURL function, it means the value of $url will be sent to the function with name getURL in your js file...
so, you have to write:
alert(e);
and if you are just asking, as the other friends told, you should use Ajax for this...
when you assign a variable to a function as an argument, just like getURL(e), the time that you call the function,getURL('print $url") you have to set the value of that variable, so, the program set the value you give to the function to the default variable...e = $url
you can change .js file to .php file and work with javascript and php together
change this
<script type="text/javascript" src="js/playthis.js"></script>
to this
<script type="text/javascript" src="js/playthis.php"></script>