Multiple xmlhttprequest on a page - javascript

I am having an error when using new XMLHttpRequest() for the second time in JavaScript code called from textbox event on page.
My JavaScript finds suggestions for text entry from the SQL to do that I use xmlhttprequest, it does fine when it is the first time but when I keep typing in the text box I receive:
"typeerror: xmlhttprequest not a costructor"
(this error happens only in Firefox)
This is my code:
function fnNull() { };
function changeofstate(){
if (XMLHttpRequest.readyState == 4)
{
whatever ;
}
XMLHttpRequest.onreadystatechange = fnNull();
}
function whentextchange(){
var WebURL = "the url here ";
XMLHttpRequest = CreateXmlHttpObject(changeOfState);
XMLHttpRequest.open("GET", WebURL, true);
XMLHttpRequest.send(null);
XMLHttpRequestt.abort();
}
}
function CreateXmlHttpObject(handler) {
var objXmlHttpReq = null;
var Req = null;
if (navigator.userAgent.indexOf("Opera")>=0)
{
return ;
}
if (navigator.userAgent.indexOf("MSIE")>=0)
{
var strName="Msxml2.XMLHTTP";
if (navigator.appVersion.indexOf("MSIE 5.5")>=0)
{
strName="Microsoft.XMLHTTP";
}
try
{
objXmlHttpReq=new ActiveXObject(strName);
objXmlHttpReq.onreadystatechange = handler;
return objXmlHttpReq;
}
catch(e)
{
return ;
}
}
if (navigator.userAgent.indexOf("Mozilla") >= 0) {
try
{
if (Req == null) {
Req = new XMLHttpRequest();
}
Req.onload = handler;
Req.onerror = handler;
return Req;
}
catch (e) {
alert(e);
alert(Req.responseText)
alert(e);
return;
}
}
}

You should name your request object something else than XMLHttpRequest. It might override the XMLHttpRequest object in the browser. Thus giving you the error.
XMLHttpRequest = CreateXmlHttpObject(changeOfState);
Assigning XMLHttpRequest variable like this is actually using global scope. You should use var and another variable name
var req = CreateXmlHttpObject(changeOfState);
Hope this clarifies.

Related

Get data from PHP to Javascript depending on Javascript variable value

I have variable _randNum in JavaScirpt which generate random number between 1 and 50.
I need to select some data from database depending on value of this variable.
I've used following JavaScript code to select data from database via PHP (but without sending JavaScript variable to PHP).
// handles the click event for link 1, sends the query
function getSuccessOutput() {
getRequest(
'questions.php', // demo-only URL
drawOutput,
drawError
);
return false;
}
// handles drawing an error message
function drawError () {
var container = document.getElementById('output');
container.innerHTML = 'Bummer: there was an error!';
}
// handles the response, adds the html
function drawOutput(responseText) {
$.getJSON("questions.php", function(theObject){
var d1 = theObject.data1; // Get the data from PHP
var d2 = theObject.data2;
}
// helper function for cross-browser request object
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req .readyState == 4){
return req.status === 200 ?
success(req.responseText) : error(req.status)
;
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
How can I send _randNum variable's value to PHP?
In PHP I could do something like that:
$rnd = mysqli_real_escape_string($con, $_POST['randNum']);
But no clue, how to send It from Javascript in same function.
I could create function like this:, but how to use It correctly with getSuccessOutput() function?
function sendFtId() {
$.post( "questions.php", { randNum : _randNum })
.done(function( data ) {
});
}
Have you any ideas?
You can use isset function to check any post request is coming or not.
E.g:
function getSuccessOutput($randNum) {
echo $randNum;
}
if(isset($_POST['randNum'])){
getSuccessOutput($_POST['randNum']);
}

XMLHttpRequest not adding header - "X-Requested-With: XMLHttpRequest"

I have an ajax call where I used jQuery.ajax() to make a request to an mvc action. This all worked fine. However due to some forms having a file control I changed it from using jQuery.ajax() to using the XMLHttpRequest to send it using the HTML5 File API.
Since making this change the MVC action method no longer see's it as an ajax request. Using Fiddler2 I have noticed that it no longer adds the "X-Requested-With: XMLHttpRequest" to the request and I assume this is the problem.
The form I am trying to send does not have a file input in it, only normal textboxes etc, but I was trying to keep the method generic to deal with both. The following is the code I am using to send the ajax request:
// get the edit tender form
var $Form = $Button.closest('form');
var Url = $Form.attr('action');
var AjaxRequestObject = new XMLHttpRequest();
var FormDataToSend = new FormData();
$Form.find(':input').each(function () {
if ($(this).is('input[type="file"]')) {
var files = $(this)[0].files;
if (files.length > 0) {
FormDataToSend.append(this.name, files[0]);
}
} else {
FormDataToSend.append(this.name, $(this).val());
}
});
AjaxRequestObject.open('POST', Url, true);
AjaxRequestObject.onreadystatechange = function () {
if (AjaxRequestObject.readyState == 4) {
// handle response.
if (AjaxRequestObject.status == 200) {
if (!AjaxErrorExists(AjaxRequestObject.responseText, )) {
alert("success");
console.log(AjaxRequestObject.responseText);
}
else {
alert('failure');
}
}
else {
alert('failure');
}
}
};
AjaxRequestObject.send(FormDataToSend);
This code was provided following a problem I had which Darin Dimitrov provided the solution to, so I could send the file inputs by ajax.
Any ideas why this request would not send the header for an ajax call?
X-Requested-With is automatically added by jQuery. You can just as easily add it yourself with AjaxRequestObject.setRequestHeader(). Docs
I was having troubles with detecting if my request was ajax. So, maybe this sample will save someone a minute or two:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', URL, true); // `true` for async call, `false` for sync.
// The header must be after `.open()`, but before `.send()`
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xmlhttp.onreadystatechange = function() {
// 4th state is the last:
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { ... }
};
xmlhttp.send();
Tested with Flask.
You can override natively all XMLHttpRequest.open method calls and add in it X-Requested-With header like:
(function () {
// #author https://github.com/stopsopa jfdsa78y453cq5hjfd7s877834h4h3
if (window.XMLHttpRequest.prototype.onOpen) {
return console.log('XMLHttpRequest.onOpen is already defined');
}
function over(method, on, off) {
var old = window.XMLHttpRequest.prototype[method];
if (!old.old) {
var stack = [];
window.XMLHttpRequest.prototype[on] = function (fn) {
if (typeof fn === 'function') {
stack.push(fn);
}
}
window.XMLHttpRequest.prototype[off] = function (fn) {
for (var i = 0, l = stack.length ; i < l ; i += 1 ) {
if (stack[i] === fn) {
stack.splice(i, 1);
break;
}
}
}
window.XMLHttpRequest.prototype[method] = function () {
var args = Array.prototype.slice.call(arguments);
var ret = old.apply(this, args);
for (var i = 0, l = stack.length ; i < l ; i += 1 ) {
stack[i].apply(this, args);
}
return ret;
}
window.XMLHttpRequest.prototype[method].old = old;
}
}
over('open', 'onOpen', 'offOpen')
XMLHttpRequest.prototype.onOpen(function () {
this.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
});
}());

Memory-leak at a wrapped XMLHttpRequest function

I wrote the following :
function ao(){
this.count=0;
this.flag=0;
this.tmr=0;
var self = this;
this.make=function(){
//log("before: "+this.url+" "+this.xhr);
self.xhr = (window.XMLHttpRequest)
? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
//log("after: "+this.xhr);
}
this.request = function (method, url, sendStr, delay){
this.delay=delay;
if(delay && self.tmr==0){
self.start();
}
if(self.flag==0){
this.method = method;
this.url = url;
this.sendStr = sendStr;
self.make();
this.xhr.open(method, url, true);
this.xhr.onreadystatechange = this.stateChange;
this.xhr.onabort=this.rrr;
this.xhr.onerror=this.rrr;
this.xhr.setRequestHeader("Cache-Control","no-cache");
this.xhr.send(sendStr);
}
};
this.repeat=function(){
if(this.flag==0){
this.flag=1;
this.count++;
this.xhr.open(self.method, self.url+"?"+this.count, true);
this.xhr.onreadystatechange = this.stateChange;
this.xhr.onabort=this.rrr;
this.xhr.onerror=this.rrr;
this.xhr.setRequestHeader("Cache-Control","no-cache");
this.xhr.send(self.sendStr);
}
return 0;
}
this.stop=function(){
window.clearInterval(this.tmr);
this.tmr=0;
this.flag=0;
}
this.start =function(){
self.tmr=window.setInterval(function(){self.repeat();},self.delay);
}
this.stateChange = function(){
if (self.xhr.readyState <= 1){
return;
self.log("404 errors");
} else {
if (self.xhr.readyState == 4 && self.xhr.status == 200){
self.resp = self.xhr.responseText;
if (self.callback != null)
self.callback(self.xhr.readyState, self.xhr.status);
else {
if (self.getHTML) {
self.getHTML(self.resp);
this.xhr=null;
} else {
if (self.xhr.readyState == 4 && self.xhr.status == 200){
self.parseJSON();
self.traverse();
this.ro=null;
this.xhr=null;
}
}
}
}
}
self.flag=0;
return 0;
};
and in windows ff there is a memory leak. I spent days trying to fix it, but I'm stumped.
The following works :
var x=new ao();
ao.request("POST","/cgi-bin/sdf.cgi","text",1000)
and after every 1000 miliseconds if previous request is done, it makes new request.
Developers should also take precautions when it comes to using the
onreadystatechanged event of an XMLHttpRequest object. If the handler
is a closure that closes over a reference to the same XMLHttpRequest
object, another circular dependency can be created. This isn't
necessairly detected by the above tool because the object is not part
of the DOM.
Link

How to access method variables from within an anonymous function in JavaScript?

I'm writing a small ajax class for personal use. In the class, I have a "post" method for sending post requests. The post method has a callback parameter. In the onreadystatechange propperty, I need to call the callback method.
Something like this:
this.requestObject.onreadystatechange = function() {
callback(this.responseText);
}
However, I can't access the callback variable from within the anonomous function. How can I bring the callback variable into the scope of the onreadystatechange anonomous function?
edit:
Here's the full code so far:
function request()
{
this.initialize = function(errorHandeler)
{
try {
try {
this.requestObject = new XDomainRequest();
} catch(e) {
try {
this.requestObject = new XMLHttpRequest();
} catch (e) {
try {
this.requestObject = new ActiveXObject("Msxml2.XMLHTTP"); //newer versions of IE5+
} catch (e) {
this.requestObject = new ActiveXObject("Microsoft.XMLHTTP"); //older versions of IE5+
}
}
}
} catch(e) {
errorHandeler();
}
}
this.post = function(url,data,callback)
{
var response;var escapedData = "";
if (typeof data == 'object') {
for (i in data) {
escapedData += escape(i)+'='+escape(data[i])+'&';
}
escapedData = escapedData.substr(0,escapedData.length-1);
} else {
escapedData = escape(data);
}
this.requestObject.open('post',url,true);
this.requestObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
this.requestObject.setRequestHeader("Content-length", data.length);
this.requestObject.setRequestHeader("Connection", "close");
this.requestObject.onreadystatechange = function()
{
if (this.readyState == 4) {
// call callback function
}
}
this.requestObject.send(data);
}
}
Just pass the callback function together with the rest of the arguments
this.post = function(url, data, callback) {
...
this.requestObject.onreadystatechange = function() {
if (this.readyState == 4) {
callback(this.responseText);
}
};
...
}
And then
foo.post("foo.html", {foo:"bar"}, function(result){
alert(result);
});
By the way, this is a better way to convert the data into a proper string
var q = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
q.push(key + "=" + encodeURIComponent(data[key]));
}
}
data = q.join("&"); //data can now be passed to .send()
encodeURIComponent is the proper function to use here as encode will not escape data properly
If you want to get a ready made function for all of this you can take a look here http://github.com/oyvindkinsey/easyXDM/blob/master/src/easyXDM.js#L358
var that = this;
Then use that instead of this inside the anonymous function.
If callback is a variable in the containing function, it should be in scope. If it is not a variable, but is in scope in in the containing function, you may have to do something like
var cb = callback;
var xhrRequest = this;
then
cb(xhrRequest.responseText);

xmlHTTPrequest won't open ("GET" , url, true); I'm miffed! PHP

I've been trying to get a url to open but I'm miffed as to why this hasn't worked. The code is listed and explained below. Any help will be deeply appreciated.
The object:
function getXMLHTTPRequest() {
var req = false;
try {
/* for Firefox */
req = new XMLHttpRequest();
} catch (err) {
try {
/* for some versions of IE */
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (err) {
try {
/* for some other versions of IE */
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (err) {
req = false;
}
}
}
return req;
}
The object is called like this:
<script type="text/javascript">
var myDelete = new getXMLHTTPRequest();
</script>
Now here's what I want to do:
function removeArticle(id) {
if (myDelete) {
try {
var deletUrl = "delete.php";
var query = deletUrl + "?theid=" + id;
myDelete.open("GET", query, true);
myDelete.onreadystatechange = removeArticleResponse;
myDelete.send(null);
} catch (e) {
alert ("Unable to connect to the server:\n" + e.toString());
}
} else {
alert ("Bad! Very BAD!");
}
}
When I do this:
if (myDelete.open("GET", query, true)) {
myDelete.onreadystatechange = removeArticleResponse;
myDelete.send(null);
} else {
alert ("No road!");
}
The alert("No road!"); shows me that the code doesn't execute passed this point:
if (myDelete.open("GET", query, true)) {
This means that the if (myDelete) { works. The code passes this stage and for some reason stops here: myDelete.open("GET", query, true); It won't open the url. I'm not sure what the problem is.
Edit: Here's the function used to access the server response:
function removeArticleResponse () {
if (myDelete.status == 4) {
if (myDelete.status == 200) {
try {
response = myDelete.responseText;
document.getElementById('displaynewsletterarticleresult').innerHTML = response;
} catch(e) {
alert("An error occured while reading the response:" + e.toString());
}
} else {
alert ("An error occured when attempting to retrieve the data:\n" + myDelete.statusText);
}
}
}
According to this, XMLHttpRequest.open() has no return value, so your check will always fail.
In your response function, do you mean to check .status == 4 instead of .readyState?
All xmlHTTPRequests are bound to the same origin policy. Maybe that's your issue.
You can read more about it at http://en.wikipedia.org/wiki/Same_origin_policy

Categories