XMLHttpRequest sends local data twice - javascript

I'm using XMLHttpRequest's send method to upload the data that are saved in a local sqlite database, to my own website. On my website I'm running phpMyAdmin. The issue that I'm having is that the data gets transmitted to the server twice, even though the local sqlite database stores the data only once. I was wondering if anyone could help me to identify the issue. I also made sure to use XMLHttpRequest asynchronously, I still don't understand why is this happening. Any help would be greatly appreciated. Thank you.
postData: function(count) {
var surveyURL = "https://example.com/data/logging/answer.php";
var file = FileUtils.getFile("ProfD", ["ext.sqlite"]);
var dbConn = Services.storage.openDatabase(file);
var query = dbConn.createStatement("SELECT * FROM responses");
var i = 0;
while (query.step()) {
let data = {
'rowid' : query.row.rowid,
'timestamp' : query.row.timestamp,
'uid' : query.row.uid,
'warning' : query.row.warning,
'ignored' : query.row.ignored,
'domain' : query.row.domain,
'qid' : query.row.qid,
'response' : query.row.response
};
let xmlhttp = Components.classes["#mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
xmlhttp.open("POST", surveyURL, true);
xmlhttp.timeout = 5000;
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
if (/^0: Survey \d+ added/.test(xmlhttp.responseText)) {
//data was added successfully, delete the row id from local database
let matches = xmlhttp.responseText.match(/^0: Survey \d+ added \((\d+)\)/);
let rowid = matches[1];
ext.Debug.dump("Deleting row " + rowid);
try {
//commented this line out, because at first I thought this was the issue but itsn't?!
//dbConn.executeSimpleSQL("DELETE FROM responses WHERE rowid=" + rowid);
} catch(e) {
ext.Debug.dump("Error deleting row: " + e);
}
} else {
ext.Debug.dump("Remote error: " + xmlhttp.responseText);
}
}
}
try {
xmlhttp.send(ext.js.toString(data));
} catch (e) {
ext.Debug.dump("Error transmitting results: " + e);
}
query.reset();
},
testConnection: function() {
//checks whether we can reach our server
//only test the connection if we have stuff to upload
//do this asynchronously
var file = FileUtils.getFile("ProfD", ["ext.sqlite"]);
var dbConn = Services.storage.openDatabase(file);
var query=dbConn.createStatement("SELECT count(*) FROM responses");
query.executeAsync({
handleResult: function(aResultSet) {
let count = aResultSet.getNextRow().getResultByIndex(0);
ext.Debug.dump(count + " records to upload");
if (count>0) {
var testURL = "https://example.com/data/connected.php";
var xmlhttp = Components.classes["#mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
xmlhttp.open("POST", testURL, true);
xmlhttp.timeout = 5000;
var date = Date.now();
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
if (xmlhttp.responseText == date) {
ext.js.postData(count);
ext.Debug.dump("connected!");
} else {
ext.Debug.dump("not connected");
}
} else {
ext.Debug.dump("not connected");
}
}
xmlhttp.ontimeout=function() {
ext.Debug.dump("not connected! 3");
}
try {
xmlhttp.send("time=" + date);
} catch (e) {
ext.Debug.dump("Error connecting: " + e);
}
}
},
handleError: function(aError) {
ext.Debug.dump("Error: " + aError.message);
},
});
dbConn.asyncClose();
},

Related

DELETE method that integrates with a Lambda Function (AWS)

I will start this by saying that I know this is probably the worst JavaScript implementation you will see but I am required to use it for academic purposes.
I am required to make a static website and deploy an API Gateway for my application with GET, POST, and DELETE methods that integrate with a Lambda Function.
My GET and POST functions are functioning well but the problem is with the DELETE.
<script>
var url = 'The API endpoint';
var submitBtn = document.getElementById('submitBtn');
submitBtn.addEventListener('click', getDetails);
function getDetails(){
var mail = document.getElementById('mail').value;
var firstName = document.getElementById('firstName').value;
if(mail == '' || firstName == ''){
alert("Please submit valid data!");
return;
}
var params = '{"Item": {"email": "' + mail + '", "firstname": "' + firstName + '"}}';
httpDeleteAsync(url, params, processResponse);
}
function httpDeleteAsync(url, params, callback){
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
callback(xmlHttp.responseText);
}
}
console.log(params);
console.log(JSON.parse(params));
xmlHttp.open("DELETE", url);
xmlHttp.setRequestHeader('Content-type', 'application/json');
xmlHttp.send(params);
}
function processResponse(response){
document.getElementById('response').innerHTML = response;
}
</script>
The console doesn't display any errors, but I get a null response on my page when I try to delete.
Thanks in advance for any help.
UPDATE #1
I am starting to think that the problem is with the Lambda function not sure if I am right though.
var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = (event, context, callback) => {
// TODO implement
//console.log(event['body-json']);
var tableName = 'Customers';
var params = {
TableName: tableName,
Item : event['body-json'].Item
}
// docClient.put(params).promise().then(res => res).catch(err => err);
docClient.delete(params, function(err, data) {
if (err) {
console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
}
});
};
I was treating the DELETE as the opposite of POST hence their processes being similar in code but I was mistaken. The DELETE had more in common with GET. So by thinking with that mindset I was able to solve the problem. Down bellow are the adjusted codes.
JAVASCRIPT:
<script>
var url = 'YOUR API'
var submitBtn = document.getElementById('submitBtn');
submitBtn.addEventListener('click', getDetails);
function getDetails(){
var mail = document.getElementById('mail').value;
if(mail == ''){
alert("Please submit a valid email!");
return;
}
var params = 'email=' + mail;
httpDelAsync(url, params, processResponse);
}
function httpDelAsync(url, params, callback){
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
callback(JSON.parse(xmlHttp.responseText));
}
}
console.log(params);
xmlHttp.open("DELETE", url + "/?" + params);
xmlHttp.send(null);
}
function isEmpty(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
function processResponse(response){
//console.log(response);
if(!isEmpty(response)){
document.getElementById('firstNameLabel').innerHTML = response.Item.firstname;
document.getElementById('mailLabel').innerHTML = response.Item.email;
document.getElementById('error').innerHTML = "";
}
else{
document.getElementById('firstNameLabel').innerHTML = '';
document.getElementById('mailLabel').innerHTML = '';
document.getElementById('error').innerHTML = "DELETED";
}
}
</script>
Lambda Function:
const AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
var tableName = "Customers" // Put your Table Name Here
exports.handler = async (event) => {
console.log(event.email)
var params = {
TableName: tableName,
Key: {
email: event.email
}
};
return docClient.delete(params).promise().then(res => res).catch(err => err);
};
There is a slight problem with the response of the DELETE but it works fine so I left it as it is.

How can i display as ajax-response in a reloaded page

I have the following situation in an AJAX-Request:
function getFileContens(OBJ) {
var file = OBJ.id;
PARAMS = "Action=getFileContens";
PARAMS = PARAMS + "&File=" + OBJ.id;
var probenZahl = file.split("__")[4];
document.getElementById("inpProbenAnzahl").value = probenZahl;
//setSessionValue(document.getElementById("inpProbenAnzahl"));
try {
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert("Ihr Webbrowser unterstuetzt leider kein Ajax!");
}
//alert(PARAMS);
req.open("POST", "./php/ajax/Eingabe.php", true);
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
req.onreadystatechange = function() {
cbGetFileContens();
};
req.send(PARAMS);
} catch (e) {
alert("Fehler: " + e);
}
}
function cbGetFileContens() {
if (4 == req.readyState) {
if (200 != req.status) {
alert("Fehler " + req.status + ": " + req.statusText);
} else {
//alert(req.responseText);
var ar_resp = req.responseText.split(";;;");
for (let i = 0; i < ar_resp.length; i++) {
ar_inp = ar_resp[i].split("##");
if (ar_inp[0].trim().length > 2) {
if (document.getElementById(ar_inp[0].trim())) {
document.getElementById(ar_inp[0].trim()).value = ar_inp[1];
}
}
}
location.reload();
//console.log("Hallo");
console.log(req.responseText);
}
}
}
This code shoud display the splitted response-text in a textfield with certain IDs in a HTML-File...
I want to use the Ajax-response-text after reloading the page..
Everything works fine whe i do not reload the page..
Using reloading the text is not displayed..
You can store the response into a session storage.
sessionStorage.setItem('ajax_response', req.responseText)
location.reload();
After, when the page is loaded, you can put the item into your element.
var el = document.getElementById('elemId')
el.innerText = sessionStorage.getItem('ajax_response')

Unable to alert success message after function executes

I am unable to get an alert of "Thank you for your enquiry!" after the function successfully executes and is sent to the database. My codes are as follows:
function addenquiry() {
Texttitle = $("#Texttitle").val();
Textenquiry = $("#Textenquiry").val();
if (validate()) {
var xmlhttp = new XMLHttpRequest();
var url = serverURL() + "/addenquiry.php";
url += "?userid=" + userid + "&Texttitle=" + Texttitle + "&Textenquiry=" + Textenquiry;
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
addEnquiry(xmlhttp.responseText);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
}
function addEnquiry(response) {
var arr = JSON.parse(response);
if (arr[0].result == 1) {
alert("Thank You for your enquiry!")
}
else {
alert("Sorry please try again");
}
}
Not sure where i have gone wrong, the title and message is successfully recorded in the database but i am not getting the alert, hope to receive some guidance and help from someone. Thank you!

XMLHttpRequest.responseXML is NULL even when .readystate == 4

I am using javascript to load in data from a XML file. The file is not being loaded in after an if statement that checks the ready state and the status. The ready state brings back 4 and the status brings back 200, so the last condition (the responseXML) should not be null, but for some reason, it remains null and the XML file is not loaded.
function load() {
try {
console.log("in load");
asyncRequest = new XMLHttpRequest();
asyncRequest.addEventListener("readystatechange", function() {
processResponse();
}, false);
asyncRequest.open('GET', 'Catalog.xml', true);
asyncRequest.send(null);
} catch (exception) {
alert("Request Failed");
console.log("failed");
}
}
function processResponse() {
console.log(asyncRequest.readyState + " response" + asyncRequest.status + asyncRequest.responseXML);
if (asyncRequest.readyState == 4 && asyncRequest.status == 200 && asyncRequest.responseXML) {
console.log("found");
var planets = asyncRequest.responseXML.getElementsByTagName("planet");
var name = document.getElementById("planetinfo").value;
console.log(name);
for (var i = 0; i < planets.length; ++i) {
var planet = planets.item(i);
var planetName = planet.getElementsByTagName("name").item(0).firstChild.nodeValue;
if (name == planetName) {
document.getElementById("name").innerHTML = planet.getElementsByTagName("name").item(0).firstChild.nodeValue;
document.getElementById("discovered").innerHTML = planet.getElementsByTagName("discovered").item(0).firstChild.nodeValue;
document.getElementById("distance").innerHTML = planet.getElementsByTagName("distance").item(0).firstChild.nodeValue;
document.getElementById("contact").innerHTML = planet.getElementsByTagName("contact").item(0).firstChild.nodeValue;
document.getElementById("image").innerHTML = "<img src='../images/" + planet.getElementsByTagName("image").item(0).firstChild.nodeValue + "' + '/ width = '250' height = '250'>";
}
}
}
}
This is the code from the javascript file that pertains to the loading of the XML. Opening up the console shows logs that tells me the code does not get past the if statement checking the asyncRequest.

Why does this JavaScript code ignore the timeout?

Question:
Consider the below JavaScript code, which works fine so far, except...
... that it completely ignores the timeout.
Why ?
I tested it with sleeping 10s in the ashx handler (timeout is set to 5s), and so far it never complained about timeout. I will increase the timeout for production use, of course.
function createXMLHttpRequest()
{
try { return new XMLHttpRequest(); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
alert("XMLHttpRequest not supported");
return null;
}
function ExecuteSQL(strParameter1, strParameter2, strParameter3)
{
try
{
strParameter1 = encodeURIComponent(strParameter1);
strParameter2 = encodeURIComponent(strParameter2);
strParameter3 = encodeURIComponent(strParameter3);
var xhReq = createXMLHttpRequest();
var dtNow = new Date();
var dt = Date.parse(dtNow) + dtNow.getMilliseconds()
var params = "prm1=" + strParameter1 + "&prm2=" + strParameter2 + "&prm3=" + strParameter3 + "&prm4=END";
params = params + "&NoCache=" + dt;
//var URLget = "cgi-bin/RequestData.ashx?NoCache=" + dt + "&param1=value1&param2=value2";
var URLpost = "cgi-bin/RequestData.ashx?NoCache=" + dt;
xhReq.open("POST", URLpost, false);
//Send the proper header information along with the request
xhReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhReq.setRequestHeader("Content-length", params.length);
xhReq.setRequestHeader("Connection", "close");
/*
xhReq.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2005 00:00:00 GMT");
*/
var MAXIMUM_WAITING_TIME = 5000;
var requestTimer = setTimeout(function () {
xhReq.abort();
alert("Request cancelled. \nReason: Timeout (" + MAXIMUM_WAITING_TIME/1000 + "s) exceeded.");
// Handle timeout situation, e.g. Retry or inform user.
}, MAXIMUM_WAITING_TIME);
xhReq.send(params);
if (xhReq.status != 200) {
clearTimeout(requestTimer);
if (xhReq.status == 400)
{
var serverResponse = xhReq.responseText;
alert(unescape(serverResponse));
}
else
alert("XMLHttpRequest Error\nHTTP Status: " + xhReq.status + "\nStatusText: " + xhReq.statusText);
}
else {
clearTimeout(requestTimer);
// Handle error, e.g. Dis
var serverResponse = xhReq.responseText;
alert("Successfully return from execution.");
//alert(unescape(serverResponse));
}
} catch (ex) {
alert("Error in JavaScript-function \"ExecuteSQL\".\nError description: " + ex.Description);
}
} // End Sub ExecuteSQL
I'm going to delete everything that has nothing to do with the timer and see if your problem becomes incredibly obvious.
function something()
{
var requestTimer = setTimeout(function () {
alert("something");
}, 1);
if (something) {
clearTimeout(requestTimer);
}
else {
clearTimeout(requestTimer);
}
}
define this variable var requestTimer outside function ExecuteSQL
You are making a synchronous call using XMLHTTPRequest. Try making it async by changing false to true in the following call:
xhReq.open("POST", URLpost, true);
Currently, due to your sync call the timeout gets cancelled.

Categories

Resources