Open XML with jQuery with maximum browser compatibility - javascript

We have a webpage using this code :
var xhr = new window.XMLHttpRequest();
// XHR for Chrome/Firefox/Opera/Safari.
// Create the XHR object.
xhr.open("GET","prp.xml", false);
xhr.send();
xmlDoc=xhr.responseXML;
It opens an XMLHttpRequest to get our XML file and then drops the result into the xmlDoc variable. I would like to know if it's possible to do that same operation using jQuery v1.11.0 and that the xmlDoc variable will still be usable by the rest of the code (aka still compatible with regular JS).
Depending on the user in here, people are using Firefox, Chrome, internet explorer 8, 9 or 10. I have read that internet explorer under 10 cannot use XMLHttpRequest, and i am pretty bad/lost with this whole jQuery thingy.
Thanks!

I'm not sure how regular JS handles XML, but an Ajax-call via jQuery is as simple as:
var xhr_variable;
$.ajax({
url: "your.xml",
success: function(data) {
console.log("working");
xhr_variable = data;
}, error: function(err) {
console.log("not working");
}
});
If you are new to Ajax, I recommend using error to check if it works or not. If works without problem, you can use the following:
var xhr_variable;
$.ajax({
url: "miep.xml",
success: function(data) {
xhr_variable = data;
}
});
Your XML-file will be assigned to your variable (if used in the correct scope).
Please note that for security reasons Ajax will only work if you call documents that are hosted on the same domain. (example.com can get documents for example.com, but not from example2.com).

Related

Different types of ajax implementation

i have just started working on ajax for my chat application which i am making in php.
While studying ajax online I cam across 2 ways in on different sites where ajax had been implemented.
What is the difference between these 2 implementations of ajax?
Any help will be greatly appreciated :)
First Implementation-
<script type"text/javascript">
$(document).ready(function() {
var dept = '<?php echo $deptId; ?>';
var interval = setInterval(function() {
$.ajax({
url: 'scripts/php/Chat.php',
data: {dept:dept},
success: function(data) {
$('#messages').html(data);
}
});
}, 1000);
});
</script>
Second Implementation-
<script language="javascript" type="text/javascript">
function ajaxFunction(){
var ajaxRequest; // The variable that makes Ajax possible!
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
}catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data
// sent from the server and will update
// div section in the same page.
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){
var ajaxDisplay = document.getElementById('ajaxDiv');
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
// Now get the value from user and pass it to
// server script.
var age = document.getElementById('age').value;
var wpm = document.getElementById('wpm').value;
var sex = document.getElementById('sex').value;
var queryString = "?age=" + age ;
queryString += "&wpm=" + wpm + "&sex=" + sex;
ajaxRequest.open("GET", "ajax-example.php" + queryString, true);
ajaxRequest.send(null);
}
Functionality-wise, it could be argued that there is no difference between them.
That said, the first "difference" between them is that the first method is using JQuery, and thus to use it, you need to have the JQuery Javascript library included in your project or the page where you need the ajax functionality. The second method, however, uses "plain ole Javascript".
Again, the first (JQuery) method, handles a lot of the "dirty" details for you, providing you with an ($.ajax) interface and requiring only that you pass in some parameters:
url : The URL you wish to call
data : The data (GET or POST) you wish to pass to the URL
success : The callback function that should be executed when the ajax request successfully returns.
In doing this, this method abstracts the internal implementation from you. For example, it handles for you the following:
browser-sniffing/capabilities detection
readyStateChange (event) checks
and some other mundane details.
Besides, also, using the second method, you can rest-assured that your code will mostly work in the majority of scenarios (if not all), if you "honour" the interface specification of the $.ajax call. Using the second method, however, you'll need to do a lot of testing and checks to ensure that your code works across all browser and platform types.
Your first code use jQuery. JQuery is a rich js lib that helps you coding quickly. See http://api.jquery.com/ (and in your particular case : http://api.jquery.com/jQuery.ajax/
Your second code is only javascript without any help from other library. It uses the XMLHttpRequest wich allows ajax call. See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
The use of jQuery is easier but some find it "overkill" :)

Internet Explorer issues running code if debugger closed

Yesterday I encountered an interesting issue with Internet Explorer. A script runs perfectly on Chrome, Firefox, Safari, but with Internet Explorer 11 it doesn't do anything. If I open the debugger it runs smoothly and everything is as it should, but the moment I close the debugger it stops working and I have no idea why is this. My first thought was the IE extensions, but I disabled them to no veil. I tried running in safe-mode, with admin rights, but nothing seems to work.
To summarize everything: IE - script runs ONLY while the debugger is On. No error is produced, it just doesn't work.
I would be really glad for any ideas what can I do regarding this. Thank you in advance.
--------------EDIT---------------
Here is the script that doesn't run.
for (var i = 0; i < AllStrategyGrids.length; i++) {
try {
isChange = true;
var data = $("#objectives").data("kendoGrid").select().data();
if (AllStrategyGrids[i].ID == data.uid) {
var jsonData = new Object();
jsonData.StrategicID = "1";
jsonData.ObjectiveID = $("#ObjectiveID").val();
jsonData.HeaderID = "00000000-0000-0000-0000-000000000000";
jsonData.PeriodID = "00000000-0000-0000-0000-000000000000";
jsonData.Strategic = "Please enter strategic";
jsonData.TaskStatus = "";
jsonData.TaskStatusID = "1";
jsonData.Position = "";
jsonData.Sorted = "1";
jsonData.SessionID = "00000000-0000-0000-0000-000000000000";
tmpGrid = AllStrategyGrids[i].Grid.data("kendoGrid");
var dataRows = tmpGrid.items();
var rowIndex = dataRows.index(tmpGrid.select());
$.ajax({
url: "CreateStrategy",
type: 'POST',
data:
{
strategics: jsonData,
VersionID: $("#VersionUID").val(),
index: rowIndex
},
success: function () {
tmpGrid.dataSource.read();
}
});
}
} catch (e) { }
}
Just a guess, this is likely because you have a console.log in that script and in IE the console object doesn't exist if your debugger is closed... we've all be there :)
An easy fix is the just add small shim as early on in your site as you can.. it won't do a thing on any browsers except IE and will just stop the execution error that probably blocking your other JS code from running...
<script>
if(!console)console={log:function(){}};
</script>
a more robust solution here :
'console' is undefined error for Internet Explorer
---- EDIT
Okay one thing i can see from your code is that you're going to fail silently because you've used a try catch but do nothing with it. This is going to catch any exception you are having (blocking it from reaching your window thus making it seem like you have no errors). I would perhaps alert the error message at the very least while testing (so you don't need to open Debugger) and see if anything is thrown...
I'd be suspecting your ajax request myself.. that or an undefined in IE8.. so add some logging alerts (brute force i know) to test your assumptions at certain points e.g.
alert("Reach here and data="+data);
Alternatively, i can also see that your ajax request has no callbacks for unsuccessful which might be good idea to add to your call. It might be that the success isn't calling for some reason...
$.ajax({
url: "CreateStrategy",
type: 'POST',
data:
{
strategics: jsonData,
VersionID: $("#VersionUID").val(),
index: rowIndex
},
success: function () {
tmpGrid.dataSource.read();
}
})
.fail(function() {
alert( "error" );
//handle a failed load gracefully here
})
.always(function() {
alert( "complete" );
//useful for any clean up code here
});
Final food for thought.
Since you're checking the DOM for an item, and i have no idea when this code is called but just in case its called directly AFTER a page reload..and lets assume something in IE isn't ready at 'that' point, it might be the DOM isn't ready to be queried yet? Try executing this code when the DOM is ready.. lots of ways to achieve this $.ready , setTimeout(f(){},1) or vanilla... but you get the idea..
Note: Debugging Script with the Developer Tools: MSDN
To enable script debugging for all instances of Internet Explorer, on
the Internet Options menu, click the Advanced tab. Then, under the
Browsing category, uncheck the Disable script debugging (Internet
Explorer) option, and then click OK. For the changes to take effect,
close all instances of Internet Explorer then reopen them again.

XML accessible from URL line but not from script

When I type a certain URL in FF, I get the XML returned displayed on the screen, so the web service is apparently working. However, when I try to access it from a local HTML document running JS, I get unexpected behavior. The returned code is "200 OK" but there's no text (or rather it's an empty string) nor xml (it's null) in the response sections according to FireBug.
This is how I make the call.
var httpObject = new XMLHttpRequest();
httpObject.open("GET", targetUrl, true);
httpObject.onreadystatechange = function () {
if (httpObject.readyState == 4) {
var responseText = httpObject.responseText;
var responseXml = httpObject.responseXML;
}
}
httpObject.send(null);
Why does it happen and how do I tackle it?
That may be an HTTP header problem (e.g. missing Accept header); observe the headers sent by FF (you can use Firebug for that) and try to replicate them in your script (setRequestHeader).
Otherwise, that may be a "same origin policy" problem.

Opera + XMLHttpRequest

I`m from Russia, so sorry for my bad English.
I want to load the main page of my site by js, and i use this script:
<script type="text/javascript">
function httpGet(theUrl) {
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
xmlHttp.send(null);
return xmlHttp.responseText;
}
alert(httpGet('http://site.ru'));
</script>
Script located at site.ru/page123.
It works in Firefox and really alert my main page, but if i run it in Opera, nothing happens. Please, fix my code, i can`t see any error in it. Thanks in advance.
XHR is usually asynchronous (switching it to synchronous mode is not recommended for reasons like freezing the browser). You better use a callback.
Since dealing with XHR manually is annoying, I'd suggest you to use jQuery. Using jQuery your code would look like this (that's just the easiest/most simple way to do it):
$.get('http://site.ru', function(resp) {
alert(resp);
});

window.onbeforeunload ajax request in Chrome

I have a web page that handles remote control of a machine through Ajax. When user navigate away from the page, I'd like to automatically disconnect from the machine. So here is the code:
window.onbeforeunload = function () {
bas_disconnect_only();
}
The disconnection function simply send a HTTP GET request to a PHP server side script, which does the actual work of disconnecting:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
});
}
This works fine in FireFox. But with Chrome, the ajax request is not sent at all. There is a unacceptable workaround: adding alert to the callback function:
function bas_disconnect_only () {
var xhr = bas_send_request("req=10", function () {
alert("You're been automatically disconnected.");
});
}
After adding the alert call, the request would be sent successfully. But as you can see, it's not really a work around at all.
Could somebody tell me if this is achievable with Chrome? What I'm doing looks completely legit to me.
Thanks,
This is relevant for newer versions of Chrome.
Like #Garry English said, sending an async request during page onunload will not work, as the browser will kill the thread before sending the request. Sending a sync request should work though.
This was right until version 29 of Chrome, but on Chrome V 30 it suddenly stopped working as stated here.
It appears that the only way of doing this today is by using the onbeforeunload event as suggested here.
BUT NOTE: other browsers will not let you send Ajax requests in the onbeforeunload event at all. so what you will have to do is perform the action in both unload and beforeunload, and check whether it had already taken place.
Something like this:
var _wasPageCleanedUp = false;
function pageCleanup()
{
if (!_wasPageCleanedUp)
{
$.ajax({
type: 'GET',
async: false,
url: 'SomeUrl.com/PageCleanup?id=123',
success: function ()
{
_wasPageCleanedUp = true;
}
});
}
}
$(window).on('beforeunload', function ()
{
//this will work only for Chrome
pageCleanup();
});
$(window).on("unload", function ()
{
//this will work for other browsers
pageCleanup();
});
I was having the same problem, where Chrome was not sending the AJAX request to the server in the window.unload event.
I was only able to get it to work if the request was synchronous. I was able to do this with Jquery and setting the async property to false:
$(window).unload(function () {
$.ajax({
type: 'GET',
async: false,
url: 'SomeUrl.com?id=123'
});
});
The above code is working for me in IE9, Chrome 19.0.1084.52 m, and Firefox 12.
Checkout the Navigator.sendBeacon() method that has been built for this purpose.
The MDN page says:
The navigator.sendBeacon() method can be used to asynchronously
transfer small HTTP data from the User Agent to a web server.
This method addresses the needs of analytics and diagnostics code that
typically attempt to send data to a web server prior to the unloading
of the document. Sending the data any sooner may result in a missed
opportunity to gather data. However, ensuring that the data has been
sent during the unloading of a document is something that has
traditionally been difficult for developers.
This is a relatively newer API and doesn't seems to be supported by IE yet.
Synchronous XMLHttpRequest has been deprecated (Synchronous and asynchronous requests). Therefore, jQuery.ajax()'s async: false option has also been deprecated.
It seems impossible (or very difficult) to use synchronous requests during beforeunload or unload
(Ajax Synchronous Request Failing in Chrome). So it is recommended to use sendBeacon and I definitely agree!
Simply:
window.addEventListener('beforeunload', function (event) { // or 'unload'
navigator.sendBeacon(URL, JSON.stringify({...}));
// more safely (optional...?)
var until = new Date().getTime() + 1000;
while (new Date().getTime() < until);
});
Try creating a variable (Boolean preferably) and making it change once you get a response from the Ajax call. And put the bas_disconnect_only() function inside a while loop.
I also had a problem like this once. I think this happens because Chrome doesn't wait for the Ajax call. I don't know how I fixed it and I haven't tried this code out so I don't know if it works. Here is an example of this:
var has_disconnected = false;
window.onbeforeunload = function () {
while (!has_disconnected) {
bas_disconnect_only();
// This doesn't have to be here but it doesn't hurt to add it:
return true;
}
}
And inside the bas_send_request() function (xmlhttp is the HTTP request):
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
has_disconnected = true;
}
Good luck and I hope this helps.
I had to track any cases when user leave page and send ajax request to backend.
var onLeavePage = function() {
$.ajax({
type: 'GET',
async: false,
data: {val1: 11, val2: 22},
url: backend_url
});
};
/**
* Track user action: click url on page; close browser tab; click back/forward buttons in browser
*/
var is_mobile_or_tablet_device = some_function_to_detect();
var event_name_leave_page = (is_mobile_or_tablet_device) ? 'pagehide' : 'beforeunload';
window.addEventListener(event_name_leave_page, onLeavePage);
/**
* Track user action when browser tab leave focus: click url on page with target="_blank"; user open new tab in browser; blur browser window etc.
*/
(/*#cc_on!#*/false) ? // check for Internet Explorer
document.onfocusout = onLeavePage :
window.onblur = onLeavePage;
Be aware that event "pagehide" fire in desktop browser, but it doesn't fire when user click back/forward buttons in browser (test in latest current version of Mozilla Firefox).
Try navigator.sendBeacon(...);
try {
// For Chrome, FF and Edge
navigator.sendBeacon(url, JSON.stringify(data));
}
catch (error)
{
console.log(error);
}
//For IE
var ua = window.navigator.userAgent;
var isIEBrowser = /MSIE|Trident/.test(ua);
if (isIEBrowser) {
$.ajax({
url: url,
type: 'Post',
.
.
.
});
}
I felt like there wasn't an answer yet that summarized all the important information, so I'm gonna give it a shot:
Using asynchronous AJAX requests is not an option because there is no guarantee that it will be sent successfully to the server. Browsers will typically ignore asynchronous requests to the server. It may, or may not, be sent. (Source)
As #ghchoi has pointed out, synchronous XMLHTTPRequests during page dismissal have been disallowed by Chrome (Deprecations and removals in Chrome 80). Chrome suggests using sendBeacon() instead.
According to Mozilla's documentation though, it is not reliable to use sendBeacon for unload or beforeunload events.
In the past, many websites have used the unload or beforeunload events to send analytics at the end of a session. However, this is extremely unreliable. In many situations, especially on mobile, the browser will not fire the unload, beforeunload, or pagehide events.
Check the documentation for further details: Avoid unload and beforeunload
Conclusion: Although Mozilla advises against using sendBeacon for this use case, I still consider this to be the best option currently available.
When I used sendBeacon for my requirements, I was struggling to access the data sent at the server side (PHP). I could solve this issue using FormData as recommended in this answer.
For the sake of completeness, here's my solution to the question:
window.addEventListener('beforeunload', function () {
bas_disconnect_only();
});
function bas_disconnect_only () {
const formData = new FormData();
formData.append(name, value);
navigator.sendBeacon('URL', formData);
}
I've been searching for a way in which leaving the page is detected with AJAX request. It worked like every time I use it, and check it with MySQL. This is the code (worked in Google Chrome):
$(window).on("beforeunload", function () {
$.ajax({
type: 'POST',
url: 'Cierre_unload.php',
success: function () {
}
})
})
To run code when a page is navigated away from, you should use the pagehide event over beforeunload. See the beforeunload usage notes on MDN.
On that event callback, you should use Navigator.sendBeacon(), as Sparky mentioned.
// use unload as backup polyfill for terminationEvent
const terminationEvent = "onpagehide" in self ? "pagehide" : "unload";
window.addEventListener(terminationEvent, (event) => {
navigator.sendBeacon("https://example.com/endpoint");
});

Categories

Resources