I need help with this problem, please help me.
I'm trying to do Ajax urlencode to PHP, but PHP doesn't show me the POST content like does when HTML send directly to PHP.
I'm using this code in Ajax to send FormData to PHP.
With this simple PHP code to see if works on php file name: "thefile.php"
With this JS, HTML and PHP code:
function sendme() {
var form = new FormData(document.forms['form']);
if (window.XMLHttpRequest)
var ajax = new XMLHttpRequest();
else
var ajax = new ActiveXObject("Microsoft.XMLHTTP");
ajax.open("post", "thefile.php", true);
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
ajax.onreadystatechange = function() {
if (ajax.readyState == 4 && ajax.status == 200)
console.log(ajax.responseText); //to see the return on in console
};
ajax.send(form);
};
<form name="form" onsubmit="return false;">
<input type="text" name="user" required autofocus/>
<input type="password" name="pass" required/>
<input type="submit" name="send" onclick="sendme();" />
</form>
<?php
print_r($_POST); //to see $_POST Array Content
echo ' '.$_POST['user'].' '.$_POST['pass'];
?>
The input content:
user: username
pass: password
The results:
Array
(
[------WebKitFormBoundary50040KVnXutLwSAd
Content-Disposition:_form-data;_name]=>"user"
username
[------WebKitFormBoundary50040KVnXutLwSAd
Content-Disposition:_form-data; name]=>"pass"
password
------WebKitFormBoundary50040KVnXutLwSAd--
)
Notice: Undefined index: user in thefile.php on line 3
Notice: Undefined index: pass in thefile.php on line 3
From the specification:
FormData: Push the result of running the multipart/form-data encoding algorithm, with object as form data set and with utf-8 as the explicit character encoding, to stream.
You are generating a multipart/form-data body, but you are explicitly setting the content-type header to claim that it is application/x-www-form-urlencoded; charset=UTF-8.
Either:
Specify the correct content type
Don't specify the content type and let XHR set it for you
It seems like your httpHeader "application/x-www-form-urlencoded" is not compatible with FormData object.
Just comment it out like below:
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
to
//ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
If you prefer to use "application/x-www-form-urlencoded; charset=UTF-8" in your request. You have to write simple javascript code to make it as normal string like:
var form = "user=root&pass=root";
.....
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
.....
ajax.send(form);
Related
I have a form that passes various types of input to an ajax call, which opens a php script. The script will do various things including processing the file, before echoing an array of variables.
All inputs go through $_POST regularly, and the file data is passed, too, but the file itself is not accessible from $_FILES.
I am not using jQuery, so most posts are hard to translate to my case.
I have seen a similar issue here,https://stackoverflow.com/questions/56878395/files-empty-after-ajax-upload but that solution doesn't seem to apply.
Here are the key excerpts from the code, thank you in advance for any tips!
var ajaxResponse = "";
var qForm = document.getElementById('myForm');
qForm.addEventListener("submit", function(e) {
e.preventDefault();
var formData = new FormData(qForm);
checkForm(formData);
console.log(ajaxResponse); //this shows the $_FILES var_dump
});
function checkForm(formData) {
var vars = "startDate=" + formData.get('startDate') +
"&qInvited=" + formData.get('qInvited');
ajaxRequestReturn("checkForm.php", vars);
}
function ajaxRequestReturn(phpRequest, vars) {
var req = new XMLHttpRequest();
req.open("POST", phpRequest, false); //not asynchronous, because I pass results to a global variable
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //removing the setRequestHeader doesn't seem to make any difference.
req.onload = function() {
ajaxResponse = this.responseText;
}
req.onerror = function() {
throw new Error("Bad request.");
}
req.send(vars);
// form.submit();
}
<form class="loginForm" id="myForm" method="post" enctype="multipart/form-data" action="thisPage.php">
<div>
<input type="date" id="startDateInput" name="startDate">
</div>
<div>
<input type="file" name="qInvited" required>
</div>
<input type="submit" id="submitBtn">
</form>
and the checkForm.php file is currently simply:
<?php
echo var_dump($_FILES);
?>
the var_dump($_FILES) should show the qInvited file in it, but it prints
array(0) {
}
instead.
To upload a file via ajax you have to pass a FormData object in your call to XMLHttpRequest.send.
Get rid of the checkForm function and call ajaxRequestReturn with formData as the second parameter.
Also, application/x-www-form-urlencoded is not the correct content type(its multipart/form-data), remove that line. The correct content type will be set automatically when you use the FormData object.
Here's the javascript function called:
function cwk_submit_form() {
var form = document.getElementById("FORM_ID")
var XHR = new XMLHttpRequest();
const FD = new FormData( form );
for (const element of FD.entries()) {
console.log(element)
}
XHR.open( "POST", "http://localhost:8080/post_data" );
XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
XHR.send( FD );
}
I left the console.log in there to mention that this does print out the correct data, meaning that the issue is seems to be in how the data is transferred.
The Golang code that receives the response is:
func post_data(w http.ResponseWriter, r *http.Request) {
log.Println("post was called")
r.ParseForm()
for key, value := range r.Form {
log.Printf("%s = %s\n", key, value)
}
}
Nothing is printed by this for loop.
If I use an HTML Form to submit like so:
<form action="//localhost:8080/post_data" method="POST">
<input type="text" name="field1" value="" maxLength="20"/>
<input type="text" name="field2" value="" maxLength="20"/>
<input type="submit" value="Sign in"/>
</form>
then the Golang code above works fine, which leads me to believe that the XMLHttpRequest format is the issue.
Your guess is right there is a problem in your js code.
For all requests, ParseForm parses the raw query from the URL and updates r.Form.
And hence, it will work when the Content-Type you send and the actual content type matches to application/x-www-form-urlencoded which happens in your HTML form case.
On the other hand, when you use FormData, it will be sent as multipart/form-data.
You need to replace your XHR.send(FD) with XHR.send(new URLSearchParams(FD)) in order to send the data in application/x-www-form-urlencoded.
This is the form:
<form id="login_form">
Login<br/>
user: <input id="login_user" name="login_user" type="text" /><br/>
pass: <input id="login_pass" name="login_pass" type="password" /><br/>
<input type="button" value="Submit" onclick="doStuff("login")" />
</form>
this is the js I used:
function doStuff(doWhat){
var sendString = new FormData(document.getElementById("login_form"));
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("POST", "?action="+doWhat, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.onreadystatechange = function(){
if(this.readyState == 4 && this.status == 200){
//do stuff
}
};
xmlhttp.send(sendString);
}
The PHP page only has echo var_dump($_POST);
If I send it like that it returns this, that I have no idea how to use:
D:\wamp64\www\test\index.php:18:
array (size=1)
'------WebKitFormBoundaryubX9lqZJrSEuJwB9
Content-Disposition:_form-data;_name' => string '"login_user"
admin
------WebKitFormBoundaryubX9lqZJrSEuJwB9
Content-Disposition: form-data; name="login_pass"
swordfish
------WebKitFormBoundaryubX9lqZJrSEuJwB9--
' (length=173)
If I try anything else, like using JSON.stringify() on the FormData before sending it or changing the content type from application/x-www-form-urlencoded to multipart/form-data it just returns an empty array. I should not use jQuery for this. Is there a way to send something usable or make the PHP page able to read it?
I am hoping this is a simple issue. I am using the Mailchimp API to submit a simple email signup form from my website. I am trying to learn javascript right now, so I am trying to do the httprequest and callback without jQuery. Basically, I am trying to convert this jQuery sample I found online to vanilla Javascript. But there is something (several things?) wrong with my javascript that I don't understand.
EDIT: When the form is submitted, I am taken to the email-validate.php page, and show the following error object returned by MailChimp.
{"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/","title":"Invalid Resource","status":400,"detail":"The resource submitted could not be validated. For field-specific details, see the 'errors' array.","instance":"","errors":[{"field":"","message":"Required fields were not provided: email_address"},{"field":"email_address","message":"Schema describes string, NULL found instead"}]}
jQuery
Found here (this actually throws an ajax(...).success is not a function error in the console but still submits the form, FWIW)
$('document').ready(function(){
$('.mc-form').submit(function(e){
//prevent the form from submitting via the browser redirect
e.preventDefault();
//grab attributes and values out of the form
var data = {email: $('#mc-email').val()};
var endpoint = $(this).attr('action');
//make the ajax request
$.ajax({
method: 'POST',
dataType: "json",
url: endpoint,
data: data
}).success(function(data){
if(data.id){
//successful adds will have an id attribute on the object
alert('thanks for signing up');
} else if (data.title == 'Member Exists') {
//MC wil send back an error object with "Member Exists" as the title
alert('thanks, but you are alredy signed up');
} else {
//something went wrong with the API call
alert('oh no, there has been a problem');
}
}).error(function(){
//the AJAX function returned a non-200, probably a server problem
alert('oh no, there has been a problem');
});
});
});
My Javascript (that doesn't work)
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("mc-form", function submit(e){
e.preventDefault();
var data = {"email": document.getElementById("mc-email").value};
var endpoint = document.getElementById("mc-form").getAttribute('action');
function formSubmit(callback){
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
//Parse returned string into an object, then pass the object to the callback function.
var response = JSON.parse(request.responseText);
callback(response);
} else {
console.log('JSON request error');
}
}
}
request.open("POST", endpoint , true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(data);
}
function formResponse(response){
if(response.id){
//successful adds will have an id attribute on the object
alert('Thank you for signing up for Launch Alerts!');
} else if (response.title == 'Member Exists') {
//MC wil send back an error object with "Member Exists" as the title
alert('You are already signed up for Launch Alerts!');
} else {
//something went wrong with the API call
alert('Something went wrong. Please resubmit the form!');
}
}
formSubmit(formResponse);
})
});
My html
<form class="mc-form" method="POST" action="./email-validate.php">
<h2 class="launch-alerts">Never miss a launch with Launch Alerts</h2>
<label for="mc-email">Email Address:</label>
<input type="email" id="mc-email" name="mc-email" autofocus="true" required/>
<input type="text" value="pending" id="status" name="status" hidden/>
<input type="submit" value="Submit">
</form>
It uses a php file to validate and submit the form, as can be seen on the link above. The html and php work to submit the form when using the jQuery script, but not my javascript, which means there is something wrong with my script, but I am too new with javascript to fully understand what it is I am trying to do, and what I am doing wrong.
Thanks!
EDIT 2:
The PHP code (copied directly from here
<?php
//fill in these values for with your own information
$api_key = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$datacenter = 'xxxxx';
$list_id = 'xxxxxxxxx';
$email = $_POST['email'];
$status = 'pending';
if(!empty($_POST['status'])){
$status = $_POST['status'];
}
$url = 'https://'.$datacenter.'.api.mailchimp.com/3.0/lists/'.$list_id.'/members/';
$username = 'apikey';
$password = $api_key;
$data = array("email_address" => $email,"status" => $status);
$data_string = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$api_key");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result=curl_exec ($ch);
curl_close ($ch);
echo $result;
?>
The data argument to request.send() must be a URL-encoded string, you're passing an object. jQuery does this conversion automatically for you; when you do it yourself, you have to do that yourself as well.
var data = "email=" + encodeURIComponent(document.getElementById("mc-email").value);
You're also not adding your submission function to the form's submit event correctly. It should be:
document.getElementById("mc-form").addEventListener("submit", function submit(e){
You can add URL Parameters manually to the URL:
var endpoint = document.getElementById("mc-form").getAttribute('action') +
"?email=" + document.getElementById("mc-email").value;
And then only do
request.send();
without the data in it.
Unable to get parameters passed from javascript to loginme.php
This is simple form in
index.php
<form method="POST">
<input type="text" id="userid" name="userid"></input>
<input type="password" id="pass" name="pass"></input>
<input type="button" value="Log in" onclick="letUserLogin()"/>
</form>
Javascript function :
myscript.js
function letUserLogin() {
var userid = document.getElementById("userid").value;
var pass = document.getElementById("pass").value;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
alert(xmlhttp.responseText); //only shows 'and'
}
}
xmlhttp.open("POST","loginme.php?userid="+userid+"&pass="+pass,true);
xmlhttp.send();
}
Simple echo statement in loginme.php
loginme.php
<?php
// username and password sent from form
$username=$_POST['userid'];
$password=$_POST['pass'];
echo"$username and $password";
?>
You are passing GET parameters:
xmlhttp.open("POST","loginme.php?userid="+userid+"&pass="+pass,true);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
... thus you need to fetch them from $_GET, not $_POST:
$username=$_GET['userid'];
$password=$_GET['pass'];
You possibly want to use the send() method instead to send your data. Right now, your payload is empty:
xmlhttp.send();
You can resolve this with JQuery quite easily if you want:
This method also allows you to put the URL within the action parameter of the form and uses POST which is more secured for transferring password information:
JQUERY:
$(document).on('submit', "form", function(e){ //We add a listener
e.preventDefault();
$.post($(this).attr('action'), $(this).serialize())
.done( function( data ) {
//Do something with response
});
});
Note that you can of course change the listener to only listen to a specific form. In this case all forms submits will be caught rather than a specific one in a page.
HTML:
<form action="/path/to/loginme.php">
<input type="text" name="userid">
<input type="password" name="pass">
</form>
PHP:
$username=$_POST['userid'];
$password=$_POST['pass'];
echo "$username and $password";
You are using POST but explicitly setting the values into the query string, GET style. So basically you are sending a blank POST.
You need to send the values like this:
xmlhttp.open("POST","loginme.php", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("userid=" + userid + "&pass=" + pass);
try this:
var userid =encodeURIComponent(document.getElementById("userid").value)
var pass =encodeURIComponent(document.getElementById("pass").value)
var parameters="userid="+userid+"&pass="+pass
mypostrequest.open("POST", "loginme.php", true)
mypostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
mypostrequest.send(parameters)
use of encodeURIComponent() to encode any special characters within the parameter values.
Call setRequestHeader() and set its content type to "application/x-www-form-urlencoded". This is needed for any POST request made via Ajax.