Passing multiple parameters by POST using XMLHttpRequest and HTML - javascript

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).

Related

$_FILES not receiving input after AJAX with vanilla Javascript

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.

My API url works in the Chrome browser, but it won't work in my test apache local host environment

When I put this into the browser, it brings back the json object just fine to me with all the weather data:
http://api.openweathermap.org/data/2.5/weather?zip=90210&units=imperial&appid={API Key}
However, I'm using my XAMPP Apache in the htdocs folder to try and test it out in my code. Can someone please look at my code and see what in the what is wrong here? Thank you so much for the help.
var weatherInfo = document.getElementById("weather");
var zipCodeForm = document.getElementById("zipCodeForm");
function getWeather(zipCode){
//create the url for the request
var endpoint = "http://api.openweathermap.org/data/2.5/weather";
var apiKey = {API Key};
var queryString = "zip=" + zipCode + "&units=imperial&appid=" + apiKey;
var url = endpoint + "?" +queryString;
//create the request to get the weather data
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", responseReceivedHandler);
xhr.requestType = "json";
xhr.open("GET", url);
xhr.send();
console.log("getWeather")
console.log(xhr.response.status);
}
function responseReceivedHandler(){
if(this.status === 200){
weatherInfo.innerHTML = "Current temperature: " + this.response.main.temp;
}
else{
weatherInfo.innerHTML="Not working";
}
console.log("responseReceivedHandler")
}
getWeather(90210);
<body>
<form id="zipCodeForm">
<label for="zipCode">Please enter your zip code: </label>
<input type="text" name="zipCode" id="zipCode">
<input type="submit" name="submit">
</form>
<div id="weather"></div>
</body>
HERE IS THE SOLUTION!!
My response needed to be converted from json to javascript object. It kept giving me undefined when I tried this.response.main.temp. The way I figured it out was the when I tried this.response[0], the result was a “{”. I was like, okay, so this must be unable to interpret this json as an object. It’s just a string of all the json characters. So I found json.parse() in order to turn it into a javascript object, and bam-- API ping success with the ability to access all the data.
Alternatively, you could just change "requestType = "json"" to responseType = json.... instead of having to parse it into an object. It's not requestType. It's responseType.

Trying to Display API Data in HTML

I am trying to make an API call and display that data on my HTML page. Currently no data is displayed when the button is clicked, but the API call is made successfully as I can track my usage on another page. My code is below:
<!DOCTYPE html>
<html>
<body>
<h1>API Data</h1>
<div id="container">
<div id="api">Nothing Yet</div>
</div>
<br>
<button type="button" onclick="loadAPI()">Change Content</button>
<script>
function loadAPI() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "API URL with Token here", false);
xhttp.addEventListener("load", loadData);
xhttp.send();
}
function loadData() {
document.getElementById('api').innerText = JSON.parse(this.responseText);
}
</script>
</body>
</html>
No data is displayed because you're not putting the data into the target element.
To insert data into #api, you need to do something like
document.getElementById('api').innerHTML = apiResponse; // no underscore
// or
document.getElementById('api').innerText = apiResponse;
I'll leave it for you to read up on security. https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
Also, XMLHttpRequest is asynchronous unless specified otherwise (in a param). So the most reliable way is to display the data in the load event listener. Your final code should be something like:
// Making a XMLHttpRequest
function loadAPI() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "API URL with Token Here", false);
xhttp.addEventListener("load", loadData);
xhttp.send();
}
// Displaying the data
function loadData() {
document.getElementById('api').innerText = this.responseText;
}
Note if your response is in JSON, you need to JSON.parse(this.responseText) to access the array/objects.

how to send images file to the url?

Here is my code:
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", "application/x-www-form-urlencoded");
// 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("success_insert").innerHTML = return_data;
}
}
// Send the data to PHP now... and wait for response to update the status div
hr.send(vars); // Actually execute the request
document.getElementById("success_insert").innerHTML = "processing...";
}
I just want to send all the basic details like First name, Middle name, Last name, and the image. The problem is, I can send the First name, Middle name, and Last name, but I can't pass the image to the LiveUpdate.php endpoint.
What's going on?
<input type="file"> element stores FileList of File objects selected by user at .files property, the .value of element is set as a string. You can set Content-Type to multipart/form-data, use FormData(), set name property of elements to query string keys, .value or .files property of <form> elements will be set at values of FormData object.
Call event.preventDefault() at submit event of <form>, pass form reference to FormData() constructor to set key, value pairs at FormData object.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form id="form1" name="form1" enctype="multipart/form-data">
<div>
First Name
<input type="text" name="FirstName" id="FirstName">
<br>Live Update
<input type="text" name="LiveUpdate" id="LiveUpdate">
<br>Image
<input type="file" id="images" name="images" accept="image/*">
</div>
<input type="submit">
</form>
<script>
var form = document.getElementById("form1");
form.onsubmit = function(e) {
e.preventDefault();
function ajax_post(form) {
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
var url = "/dev/null";
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("success_insert").innerHTML = return_data;
}
}
// Send the data to PHP now... and wait for response to update the status div
hr.send(new FormData(form)); // Actually execute the request
// document.getElementById("success_insert").innerHTML = "processing...";
}
ajax_post(this)
}
</script>
</body>
</html>

XMLHttpRequest to Post HTML Form

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

Categories