Let's say I'm trying to send a data to PHP and receive it using pure Javascript.
So when I'm sending a string "login="+1+"&username="+username+"&password="+password; with Ajax It's all ok but what about an Object? in this case, my PHP code always telling username and password are Undefined indexes.
HTML Document :
<body>
<form id="loginform">
<input type="text" placeholder="username" id="username" required autocomplete="off"><br>
<input type="password" placeholder="password" id="password" required><br>
<input type="submit" id="submit">
</form>
<script>
document.getElementById("loginform").addEventListener("submit", function(e) {
e.preventDefault();
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var data = {// ---- there is my Object -----
login: 1,
username: username,
password: password
}
var xhr = new XMLHttpRequest();
xhr.open("POST", "process.php", true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
console.log(this.responseText);
}
xhr.send(data);
});
</script>
</body>
PHP Document :
<?php
if(isset($_POST["login"])) {
$username = $_POST['username'];
$password = $_POST['password'];
echo($username . " , " . $password);
}
?>
what about an Object?
send() doesn't expect to be passed a plain object, so it converts it by calling its toString() method, which gives you "[object Object]", which (obviously) isn't URL encoded data.
Not only does PHP not understand it, but the data you want to send isn't included in it in the first place.
If you have an object, you need to convert it into a format that you can decode on the server.
Continuing to use form encoded data is the simplest approach.
var data = {
login: 1,
username: "example",
password: "example"
};
var key_value_pairs = [];
Object.keys(data).forEach(function(key) {
key_value_pairs.push(
encodeURIComponent(key) + "=" + encodeURIComponent(data[key])
);
})
var url_encoded_string = key_value_pairs.join("&");
console.log(url_encoded_string);
You could also send the data using a different format. PHP understands multipart MIME encoding which you can generate with a FormData object.
var form_data = new FormData(document.getElementById("loginform"));
form_data.append("login", "1");
xhr.send(form_data);
If you do this, do not override the Content-Type with:
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
XMLHttpRequest will generate the correct-content type, with the multipart MIME boundary parameter from the FormData object.
You could also encode the data with a different data format, such as JSON:
xhr.setRequestHeader('Content-type', 'application/json');
xhr.send(JSON.stringify(data));
… but, and this is a big but, PHP does not know how to decode JSON formatted requests and will not automatically populate $_POST.
You would need to change the PHP to read the data:
$json = file_get_contents('php://input')
$data = json_decode($json));
var_dump($data);
Related
I would like to send the data to another php page using javascript but it does not work as expected.
Let just say I have the form:
<form id="myForm">
<label for="name">Username</label>
<input type="text" name="name" id="name">
<label for="pass">Password</label>
<input type="password" name="pass" id="pass">
<button id="submit" type="submit" >OK</button>
</form>
and the script:
const myForm = document.getElementById('submit');
myForm.addEventListener('submit', function(e){
e.preventDefault();
const data = new FormData(this);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'getData.php', true);
xhr.onload = function () {
// do something to response
console.log(this.responseText);
};
xhr.send(data);
});
The php file is unable to recieve the data at the moment. How can it fix with ajax or any other equivalent code?
Make change in button
<button id="submit" type="button" onclick="sendData()" >OK</button>
Then add javascript function.
<script>
function sendData(){
var name = document.getElementById("name");
var password = document.getElementById("pass");
if (name) {
$.ajax({
type:"POST",
url:"path-to-php-file.php",
data:'name='+name+'&pass='+password,
success:function(data){
alert(data);
}
});
}
</script>
Then create php file where you will get data.
path-to-php-file.php
<?php
$name = $_POST['name'];
$password = $_POST['pass'];
echo $name .'--'.$password;
?>
I cannot tell exactly what is the problem without looking at your php code.
Maybe there is something wrong with the Content-Type header.
document.getElementById('submit').addEventListener('submit', (e) => {
e.preventDefault();
const data = new FormData(this); // Here 'this' will not work, you gotta loop through the inputs and append them to the FormData object.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
// do something
}
xhr.open('POST', 'getData.php', true);
// the default content type is application/x-www-form-urlencoded
xhr.setRequestHeader("Content-Type", "<content type here>")
xhr.send(data);
});
Extra
What I suggest is in your case you won't really need a form element here. You could make the button a normal button and make the form a div(not special benefit, just for clean code). Assign a function to the onclick event of the button and loop through the inputs and append them to the form data(if the content type is application/x-www-form-urlencoded) object and send it to the server.Use this method if you have a complex form like a interactive form like Google or Microsoft have.
And also you do not want to use preventDefault() method if you follow my method.
This is what most professionals would do.
My data is not inserting into database, I get a blank response from the console log and network. I'm kinda lost my javascript source code is mix with other stack overflow answers as well as my PHP code.
<form id="requestForm">
<input type="text" name="fName" id="name">
<input type="text" name="fAddress" id="address">
<input type="text" name="fComment" id="comment">
<input type="submit" value="Submit" name="nameSubmit">
</form>
<script>
document.querySelector('#requestForm').addEventListener('submit', postRequest);
function postRequest(e){
e.preventDefault();
const params = {
fName: document.querySelector('#name').value,
fAddress: document.querySelector('#address').value,
fComment: document.querySelector('#comment').value,
};
var xhr = new XMLHttpRequest();
xhr.open('POST', 'addRequest.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function(){
console.log(this.responseText);
}
xhr.send(params);
}
</script>
</body>
Here's the PHP code:
require_once 'Database.php';
var_dump($_POST); // returns `array(0) {}`
if (isset($_POST['nameSubmit'])) {
var_dump($_POST); // shows no response
$r = $_POST['fName'];
$o = $_POST['fAddress'];
$p = $_POST['fComment'];
$query = "INSERT INTO user_request(name, address, comment) VALUES(?,?,?)";
$stmt = $db->prepare($query);
$insert = $stmt->execute([$r, $o, $p]);
if($insert){
echo 'Success';
}else{
echo 'Error';
}
}
I believe the post parameter nameSubmit does not exsist.
Use the var_dump() function for dump all $_POST
From my prespective, the only parameter given was
fName
fAddress
fComment
Why not check for request method instead?
This is better than checking if a variable exsisted or not.
You can do the checks for required parameter later after you're sure this is a POST request.
if($_SERVER['REQUEST_METHOD'] === 'POST'){
// Do whatever you want when POST request came in
}
UPDATE :
Here is the answer you wanted!
<form id="requestForm">
<input type="text" name="fName" id="name">
<input type="text" name="fAddress" id="address">
<input type="text" name="fComment" id="comment">
<button onclick="sendData();" type="button">Submit</button>
</form>
<div id="testdiv"></div>
<script>
function sendData(){
var data = new FormData();
data.append('fName', document.getElementById("name").value);
data.append('fAddress', document.getElementById("address").value);
data.append('fComment', document.getElementById("comment").value);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php', true);
xhr.onload = function () {
if(xhr.status !== 200){
// Server does not return HTTP 200 (OK) response.
// Whatever you wanted to do when server responded with another code than 200 (OK)
return; // return is important because the code below is NOT executed if the response is other than HTTP 200 (OK)
}
// Whatever you wanted to do when server responded with HTTP 200 (OK)
// I've added a DIV with id of testdiv to show the result there
document.getElementById("testdiv").innerHTML = this.responseText;
};
xhr.send(data);
}
</script>
</body>
The PHP code :
<?php
if($_SERVER['REQUEST_METHOD'] === 'POST'){
var_dump($_POST);
}else{
header('HTTP/1.0 403 Forbidden');
}
?>
To add another field, add another data.append function below data var.
The submit button MUST BE CLICKED. To allow the use of enter, add an event listener for it!.
What it looks like on my end : https://image.ibb.co/gfSHZK/image.png
Hope this is the answer you wanted.
Two issues:
1.) Params not sent properly/at all because lack of serialization. When you use form content-type your params object need to be in a particular format name=value&name2=value2. So to facilitate that you need to transform your ojbect using something like:
function getReadyToSend(object) {
var objList = [];
for (var prop in object) {
if (object.hasOwnProperty(prop)) {
objList.push(encodeURI(prop + '=' + object[prop]));
}
}
return objList.join("&");
}
So your sending becomes: xhr.send(getReadyToSend(params));
2) Your php is expecting the submit button to be sent. if (isset($_POST['nameSubmit'])) {
You don't have a variable being sent called nameSubmit you can fix this by either including it or check that each variable is set instead. I would suggest the latter that way you can error handle should 1 or more are not passed.
Suggestion: Update your onload to check status:
if (xhr.status === 200)
{
console.log(xhr.responseText);
}
else if(xhr.status !== 200)
{
console.log('Request failed. Returned status of ', xhr.status);
}
Example fiddle: http://jsfiddle.net/qofrhemp/1/, open network tab and inspect the call you will now see the params in form data for the call that fires when submit clicked.
This script is designed to get the values from the inputs and send it by ajax to x.php as POST data to be echo by x.php. This works perfectly but I want to convert
this jQuery structure to a pure JavaScript structure so in other words how can I send a basic JS Object contents as POST data by AJAX to be echo by x.php
jQuery structure(works*)
index.php
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#send').click(function(){
//Var structure
var first_name= $('#first_name').val();
var last_name= $('#last_name').val();
//Data var
var data={
first_name: first_name,
last_name: last_name
}
//Success var
var success= function(response){
$('.output-container').html(response);
}
//Request
$.ajax({
data: data,
method: 'POST',
url: 'x',
success: success
});
});
});
</script>
<input id='first_name' type='text' value='John'>
<input id='last_name' type='text' value='Doe'>
<button id='send'>Send</button>
<div class='output-container'><div>
JavaScript structure(Failed attempt*)
index.php
<script>
document.addEventListener('DOMContentLoaded', function(){
var execute_sendAjax = document.getElementById('send');
execute_sendAjax.addEventListener("click", executeAjax);
var xhr= new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
document.getElementsByClassName('output-container')[0].innerHTML= xhr.responseText;
}
};
function executeAjax(){
//Var structrue
var first_name= document.getElementById('first_name').value;
var last_name= document.getElementById('last_name').value;
//Data var
var data={
first_name: first_name,
last_name: last_name
}
xhr.open('POST','x');
xhr.send();
}
});
</script>
<input id='first_name' type='text' value='John'>
<input id='last_name' type='text' value='Doe'>
<button id='send'>Send</button>
<div class='output-container'><div>
x.php
<?php
$first_name=$_POST['first_name'];
$last_name=$_POST['last_name'];
?>
<h1><?php echo $first_name; ?></h1>
</h1><?php echo $last_name; ?></h1>
In the pure JS structure I don't know where to go from there that's where I'm getting stuck at.
Recent findings UPDATED*
After doing some more research(Link) I found out that application/x-www-form-urlencoded is another way to encode as POST data but I had to avoid using a JS object because it does not work with a normal JS object. I'm still looking for a way that I can use as a JS object.
<script>
document.addEventListener('DOMContentLoaded', function(){
var execute_sendAjax = document.getElementById('send');
execute_sendAjax.addEventListener("click", executeAjax);
var xhr= new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
document.getElementsByClassName('output-container')[0].innerHTML= xhr.responseText;
}
};
function executeAjax(){
//Var structrue
var first_name= document.getElementById('first_name').value;
var last_name= document.getElementById('last_name').value;
//Data var
var data = "first_name="+first_name+"&last_name="+last_name;
/*var data={
first_name: first_name,
last_name: last_name
}*/
xhr.open('POST','x');
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //<--I notice this makes it encoded to be used as POST data
xhr.send(data);
}
});
</script>
<input id='first_name' type='text' value='John'>
<input id='last_name' type='text' value='Doe'>
<button id='send'>Send</button>
<div class='output-container'><div>
JQuery is marshaling the Javascript object into form data. There are lots of ways to do this, but I think the easiest way is to use a FormData object like so:
function executeAjax(){
var data = new FormData();
// FormData.append(name, value) - appends a new value onto an
// existing key inside a FormData object, or adds the key if
// it does not already exist.
data.append("first_name", document.getElementById('first_name').value;);
data.append("last_name", document.getElementById('last_name').value;
xhr.open('POST','x.php');
xhr.send(data);
}
Then you don't have to edit any PHP or set the content-type in the request header.
If you don't like the FormData object (for whatever reason):
function executeAjax(data) {
var data = [
"first_name="+encodeURIComponent(document.getElementById('first_name').value),
"last_name="+encodeURIComponent(document.getElementById('last_name').value)
].join('&').replace(/%20/g, '+');
xhr.open('POST', 'x.php');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(data);
}
Learn more here.
Sorry was not at the computer before.
This is my javascript
function ajax_post(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
var url = "LiveUpdate.php";
var sb = document.getElementById("LiveUpdate").value;
var FirstName = document.getElementById("FirstName").value;
var images = document.getElementById("images").value;
var vars = "update="+sb+"&FirstName="+FirstName+"&images="+images;
hr.open("POST", url, true);
// Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "multipart/form-data");
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var return_data = hr.responseText;
document.getElementById("message").innerHTML = return_data;
}
}
// Send the data to PHP now... and wait for response to update the status div
var formData = new FormData(document.querySelector("form"));
hr.send(formData); // Actually execute the request // Actually execute the request
document.getElementById("message").innerHTML = "processing...";
}
//show image before uploading
var loadFile = function(event) {
var output = document.getElementById('output');
output.src = URL.createObjectURL(event.target.files[0]);
};//end image
and this is the form. javascript and the form is in the same file. the file name is sample.php
<form action="popup.php" method="post" id="myForm" name="myForm" enctype="multipart/form-data">
<div id="message"></div>
<img src="" id="output" />
<input type="file" class="filestyle" data-buttonBefore="true" accept=".png, .jpg, .jpeg" onchange="loadFile(event)" name="images" id="images">
<input class="form-control" type="text" placeholder="First Name" name="FirstName" id="FirstName" value="">
Update
</form>
the idea in this code is. i want to insert the basic information like FirstName and Image into the database live without refreshing the page. the reason why i choose tag to submit the ajax. so the page url Account.php?Edit=1 will not change to Account.php because if it change to account.php the popup editing mode will be close. the problem in this code is. i don't know how to fix the error Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0 can anyone help me how to fix this. thank you!
The browser sets the correct headers (including the correct multipart boundary indication in the Content-type) if you haven't manually specified anything.
So all you need to do is remove the following line:
hr.setRequestHeader("Content-type", "multipart/form-data");
Otherwise you will need to set the boundary yourself as it is suggested by Ellias Van Ootegem in Uploading a file with XMLHttprequest - Missing boundary in multipart/form-data:
hr.setRequestHeader("Content-type","multipart/form-data; charset=utf-8; boundary=" + Math.random().toString().substr(2));
Just remove the setRequestHeader()
This works as well. Taken from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
const config = {
headers: {
Authorization: Bearer ${localStorage.token},
"Content-Type":
"multipart/form-data; boundary=---------------------------974767299852498929531610575"
}
};
am very new to ajax. and currently learning how it works!
so created a new instance of FormData while passing it my form.
then i went through the basic ajax rituals: opened a request, set the request header, then send data.
but still i got a very weird response when i tried viewing the $_POST array in PHP with var_dump.
// HTML FORM
<form id="myForm" action="ajax_response.php" method="post">
<input type="text" name="name">
<button type="submit">submit</button>
</form>
// JAVASCRIPT AJAX
var req = new XMLHttpRequest();
var fData = new FormData(myForm);
req.open('post','ajax_response.php',true);
req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
req.send(fData);
req.onload = function() {
document.write(this.responsText);
};
// PHP
if(isset($_POST)) {
var_dump($_POST);
}
// RESPONSE
array (size=1)
'------WebKitFormBoundaryAzMVL1V93W6RKYOA
Content-Disposition:_form-data;_name' => string '"name"
test
------WebKitFormBoundaryAzMVL1V93W6RKYOA--
'
i later got a desire response by commenting out the req.setRequestHeader line.
array (size=1)
'name' => string 'test'
but i'll like for somebody to please explain to me why i can't send FormData over a Content-Type: application/x-www-form-urlencoded header.