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.
Related
I'm trying to pass multiple parameters via HTML form into a XMLHttpRequest. The request takes a network SSID and PSK and passes it to the /connect endpoint.
It works when I hardcode the SSID and PSK using:
var data = '{"ssid":"homenetwork", "psk":"mypassword"}';
xhr.send(data);
When I try to pull the data from the HTML form I get net::ERR_EMPTY_RESPONSE in Chrome.
<!DOCTYPE html>
<html>
<br>
<label for="network">Network Name (SSID):</label>
<input type="text" id="network" name="network" required size="15">
<label for="presharedkey">Network Password (PSK): </label>
<input type="text" id="presharedkey" name="presharedkey" required size="15">
<button onclick="connectWifi()">Save</button> <br>
<script>
function connectWifi() {
var network = document.getElementById("network") .value;
var presharedkey = document.getElementById("presharedkey") .value;
var url = "http://192.168.0.236:8080/connect";
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log(xhr.status);
console.log(xhr.responseText);
}};
// var data = '{"ssid":"homenetwork", "psk":"mypassword"}';
var data = 'ssid='+network+'&psk='+presharedkey;
xhr.send(data);
}
</script>
</html>
The var data = line I pulled from this StackOverflow question.
Thanks in advance.
The data variable you are using needs to be a JSON object. In your example here it is a string, so the individual values are not passed, just one single string.
Try:
var data = `{"ssid": "${network}", "psk": "${presharedkey}"}`;
[EDIT]
I misunderstood the original question it seems. OP is trying to send the data as a JSON object but doesn't know how to format it (they claim manually passing the string of variables works).
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.
I want to input a bulk list of urls in a textarea (each line contains 1 url). After submitting the form, the ajax should get one url, doing php stuff with this url, sending the result back, take another url, do the same and repeat. While the hole thing is working there should be displayed a loading circle ("ajax-loader.gif") and the results should be displayed one after another, like:
[Submit] -> loading -> result 1st-url -> loading -> add result 2nd-url one line under result 1st-url -> loading -> add result 3rd-url one line under result 2nd-url -> ...
I'm doing this whole ajax/js stuff since yesterday - so i'm not very experienced in that way - the php is working with no errors. my main problem is the js/ajax request; how to recieve the result, doing stuff with it,.. This is what i've written so far:
js/ajax (w.o. jquery cause i dont like the notation):
function send (){
var url = document.getElementById('comment').value.split('\n'); //split input from textarea in array
document.getElementById("load").innerHTML='<img src="ajax-loader.gif" />';
for(var i=0;i<url.length;i++) {
http = new XMLHttpRequest();
http.open("POST", "check.php", true);
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
http.send("name=" + url[i]);
http.onreadystatechange=function() {
if (http.readyState == 4) {
document.getElementById("result").innerHTML=http.responseText;
}
}
}
}
html:
<form method="post" action="" name="Formular">
<textarea cols="100" rows="10" id="comment"></textarea><br/>
<input type="button" value="Absenden" onClick="send()">
</form>
<div id="load"></div>
<div id="result"></div>
php:
<?php
$url = $_POST['name']; //get url
..do funky stuff..
echo $result; //result is a simple string if an element on that url exists
?>
What you need to do is make your ajax function recursive, eg on completion, it calls its self, rather than using a loop.
Here is a full example, contained in a single php file, called ajax-example.php:
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
sleep(1);
echo $_POST['name'];
die();
}
?>
<html>
<head></head>
<body>
<div id="load">doin nothin</div>
<textarea name="n" id="comment" cols="30" rows="10"></textarea>
<br/>
<button onclick="send()">send</button>
<div id="result"></div>
<script type="application/javascript">
function send (){
var url = document.getElementById('comment').value.split('\n'); //split input from textarea in array
var current = 0;
var total = url.length;
document.getElementById("load").innerHTML='loading';//'<img src="ajax-loader.gif" />';
//call ajax for 1st time
ajax();
function ajax(){
//if there are urls left to process
if(current < total){
var http = new XMLHttpRequest();
http.open("POST", "/ajax-example.php", true);
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
http.send("name=" + url[current]);
//increment current marker
current++;
http.onreadystatechange=function() {
if (http.readyState == 4) {
var res = document.getElementById("result");
res.innerHTML=res.innerHTML + http.responseText +"</br>";
//recursive call
ajax();
}
}
}else{
//we are done, remove the loading img
document.getElementById("load").innerHTML='finished';
}
}
}
</script>
</body>
</html>
Just to add, dont discount jQuery just because you dont like the syntax, it can make your life a lot easier for non trivial dom manipulation
Current Setup
I have an HTML form like so.
<form id="demo-form" action="post-handler.php" method="POST">
<input type="text" name="name" value="previousValue"/>
<button type="submit" name="action" value="dosomething">Update</button>
</form>
I may have many of these forms on a page.
My Question
How do I submit this form asynchronously and not get redirected or refresh the page? I know how to use XMLHttpRequest. The issue I have is retrieving the data from the HTML in javascript to then put into a post request string. Here is the method I'm currently using for my zXMLHttpRequest`'s.
function getHttpRequest() {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
function demoRequest() {
var request = getHttpRequest();
request.onreadystatechange=function() {
if (request.readyState == 4 && request.status == 200) {
console.log("Response Received");
}
}
request.open("POST","post-handler.php",true);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send("action=dosomething");
}
So for example, say the javascript method demoRequest() was called when the form's submit button was clicked, how do I access the form's values from this method to then add it to the XMLHttpRequest?
EDIT
Trying to implement a solution from an answer below I have modified my form like so.
<form id="demo-form">
<input type="text" name="name" value="previousValue"/>
<button type="submit" name="action" value="dosomething" onClick="demoRequest()">Update</button>
</form>
However, on clicking the button, it's still trying to redirect me (to where I'm unsure) and my method isn't called?
Button Event Listener
document.getElementById('updateBtn').addEventListener('click', function (evt) {
evt.preventDefault();
// Do something
updateProperties();
return false;
});
The POST string format is the following:
name=value&name2=value2&name3=value3
So you have to grab all names, their values and put them into that format.
You can either iterate all input elements or get specific ones by calling document.getElementById().
Warning: You have to use encodeURIComponent() for all names and especially for the values so that possible & contained in the strings do not break the format.
Example:
var input = document.getElementById("my-input-id");
var inputData = encodeURIComponent(input.value);
request.send("action=dosomething&" + input.name + "=" + inputData);
Another far simpler option would be to use FormData objects. Such an object can hold name and value pairs.
Luckily, we can construct a FormData object from an existing form and we can send it it directly to XMLHttpRequest's method send():
var formData = new FormData( document.getElementById("my-form-id") );
xhr.send(formData);
The ComFreek's answer is correct but a complete example is missing.
Therefore I have wrote an extremely simplified working snippet:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>
<script>
"use strict";
function submitForm(oFormElement)
{
var xhr = new XMLHttpRequest();
xhr.onload = function(){ alert(xhr.responseText); }
xhr.open(oFormElement.method, oFormElement.getAttribute("action"));
xhr.send(new FormData(oFormElement));
return false;
}
</script>
</head>
<body>
<form method="POST"
action="post-handler.php"
onsubmit="return submitForm(this);" >
<input type="text" value="previousValue" name="name"/>
<input type="submit" value="Update"/>
</form>
</body>
</html>
This snippet is basic and cannot use GET. I have been inspired from the excellent Mozilla Documentation. Have a deeper read of this MDN documentation to do more. See also this answer using formAction.
By the way I have used the following code to submit form in ajax request.
$('form[id=demo-form]').submit(function (event) {
if (request) {
request.abort();
}
// setup some local variables
var $form = $(this);
// let's select and cache all the fields
var $inputs = $form.find("input, select, button, textarea");
// serialize the data in the form
var serializedData = $form.serialize();
// fire off the request to specific url
var request = $.ajax({
url : "URL TO POST FORM",
type: "post",
data: serializedData
});
// callback handler that will be called on success
request.done(function (response, textStatus, jqXHR){
});
// callback handler that will be called on failure
request.fail(function (jqXHR, textStatus, errorThrown){
});
// callback handler that will be called regardless
// if the request failed or succeeded
request.always(function () {
// reenable the inputs
});
// prevent default posting of form
event.preventDefault();
});
With pure Javascript, you just want something like:
var val = document.getElementById("inputFieldID").value;
You want to compose a data object that has key-value pairs, kind of like
name=John&lastName=Smith&age=3
Then send it with request.send("name=John&lastName=Smith&age=3");
I have had this problem too, I think.
I have a input element with a button. The onclick method of the button uses XMLHTTPRequest to POST a request to the server, all coded in the JavaScript.
When I wrapped the input and the button in a form the form's action property was used. The button was not type=submit which form my reading of HTML standard (https://html.spec.whatwg.org/#attributes-for-form-submission) it should be.
But I solved it by overriding the form.onsubmit method like so:
form.onsubmit = function(E){return false;}
I was using FireFox developer edition and chromium 38.0.2125.111 Ubuntu 14.04 (290379) (64-bit).
function postt(){
var http = new XMLHttpRequest();
var y = document.getElementById("user").value;
var z = document.getElementById("pass").value;
var postdata= "username=y&password=z"; //Probably need the escape method for values here, like you did
http.open("POST", "chat.php", true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", postdata.length);
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(postdata);
}
how can I post the values of y and z here from the form
Here's how the situation looks :
I have a couple simple forms
<form action='settings.php' method='post'>
<input type='hidden' name='setting' value='value1'>
<input type='submit' value='Value1'>
</form>
Other small forms close to it have value2, value3, ... for the specific setting1, etc.
Now, I have all these forms placed on the settings.php subpage, but I'd also like to have copies of one or two of them on the index.php subpage (for ease of access, as they are in certain situations rather frequently used).
Thing is I do not want those forms based on the index.php to redirect me in any way to settings.php, just post the hidden value to alter settings and that's all.
How can I do this with JS ?
Cheers
Yes, you could use an ajax call to send a request to the settings.php file. You'd probably want that PHP code to return something that the JavaScript can use to know if the request was successful or not (for example, using JSON instead of HTML).
Here is an ajax getData function.
function getData(dataSource, targetDiv){
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest) {
XMLHttpRequestObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
XMLHttpRequestObject = new
ActiveXObject("Microsoft.XMLHTTP");
}
if(XMLHttpRequestObject) {
var obj = document.getElementById(targetDiv);
XMLHttpRequestObject.open("GET", "settings.php?form="+dataSource+"&t="+new Date().getTime());
XMLHttpRequestObject.onreadystatechange = function()
{
if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) {
obj.innerHTML = XMLHttpRequestObject.responseText;
}
}
XMLHttpRequestObject.send(null);
}
}
use this function to send the form to your setting.php file which should return confirmation message to index.php(inside targetDiv).
Parameters of the function
1) dataSource - is the variable value that you send to settings.php
2) targetDiv - is the div on index php that with display the response from settings.php
Hope it makes sense.