we are currently working on an application that works fine with wifi and has an offline version and once they have finished the user can upload the results to the online database. The issue were experiencing is that so of the ids are not matching up when using mobile data (3G/4G). Has anyone else experienced this similar problem using HTTPClient, below is an example of my httpclient, am i missing something that will help prevent this or any other suggestions?
I know NETWORK_ENABLED will still perform the sync as mobile data is under the NETWORK_ENABLED, but is there a way to see if connection is lost?
this.sendToServer = function(params, httpParams) {
if (Alloy.Globals.NETWORK_ENABLED){
var xhr = Ti.Network.createHTTPClient(params);
xhr.validatesSecureCertificate = false;
xhr.open('POST', this.url, true);
xhr.send(httpParams);
} else {
params.onload();
}
};
The only thing I can recommend is this module here: https://github.com/benbahrenburg/Pinger
But I've never used it. Checking the example .js file, seems to only ping www.apple.com and give you a "yes" or "no".
Could be quite useful actually =)
Related
This question already has answers here:
Detect the Internet connection is offline?
(22 answers)
Closed 8 years ago.
How do you check if there is an internet connection using jQuery? That way I could have some conditionals saying "use the google cached version of JQuery during production, use either that or a local version during development, depending on the internet connection".
The best option for your specific case might be:
Right before your close </body> tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>
This is probably the easiest way given that your issue is centered around jQuery.
If you wanted a more robust solution you could try:
var online = navigator.onLine;
Read more about the W3C's spec on offline web apps, however be aware that this will work best in modern web browsers, doing so with older web browsers may not work as expected, or at all.
Alternatively, an XHR request to your own server isn't that bad of a method for testing your connectivity. Considering one of the other answers state that there are too many points of failure for an XHR, if your XHR is flawed when establishing it's connection then it'll also be flawed during routine use anyhow. If your site is unreachable for any reason, then your other services running on the same servers will likely be unreachable also. That decision is up to you.
I wouldn't recommend making an XHR request to someone else's service, even google.com for that matter. Make the request to your server, or not at all.
What does it mean to be "online"?
There seems to be some confusion around what being "online" means. Consider that the internet is a bunch of networks, however sometimes you're on a VPN, without access to the internet "at-large" or the world wide web. Often companies have their own networks which have limited connectivity to other external networks, therefore you could be considered "online". Being online only entails that you are connected to a network, not the availability nor reachability of the services you are trying to connect to.
To determine if a host is reachable from your network, you could do this:
function hostReachable() {
// Handle IE and more capable browsers
var xhr = new ( window.ActiveXObject || XMLHttpRequest )( "Microsoft.XMLHTTP" );
// Open new request as a HEAD to the root hostname with a random param to bust the cache
xhr.open( "HEAD", "//" + window.location.hostname + "/?rand=" + Math.floor((1 + Math.random()) * 0x10000), false );
// Issue request and handle response
try {
xhr.send();
return ( xhr.status >= 200 && (xhr.status < 300 || xhr.status === 304) );
} catch (error) {
return false;
}
}
You can also find the Gist for that here: https://gist.github.com/jpsilvashy/5725579
Details on local implementation
Some people have commented, "I'm always being returned false". That's because you're probably testing it out on your local server. Whatever server you're making the request to, you'll need to be able to respond to the HEAD request, that of course can be changed to a GET if you want.
Ok, maybe a bit late in the game but what about checking with an online image?
I mean, the OP needs to know if he needs to grab the Google CMD or the local JQ copy, but that doesn't mean the browser can't read Javascript no matter what, right?
<script>
function doConnectFunction() {
// Grab the GOOGLE CMD
}
function doNotConnectFunction() {
// Grab the LOCAL JQ
}
var i = new Image();
i.onload = doConnectFunction;
i.onerror = doNotConnectFunction;
// CHANGE IMAGE URL TO ANY IMAGE YOU KNOW IS LIVE
i.src = 'http://gfx2.hotmail.com/mail/uxp/w4/m4/pr014/h/s7.png?d=' + escape(Date());
// escape(Date()) is necessary to override possibility of image coming from cache
</script>
Just my 2 cents
5 years later-version:
Today, there are JS libraries for you, if you don't want to get into the nitty gritty of the different methods described on this page.
On of these is https://github.com/hubspot/offline. It checks for the connectivity of a pre-defined URI, by default your favicon. It automatically detects when the user's connectivity has been reestablished and provides neat events like up and down, which you can bind to in order to update your UI.
You can mimic the Ping command.
Use Ajax to request a timestamp to your own server, define a timer using setTimeout to 5 seconds, if theres no response it try again.
If there's no response in 4 attempts, you can suppose that internet is down.
So you can check using this routine in regular intervals like 1 or 3 minutes.
That seems a good and clean solution for me.
You can try by sending XHR Requests a few times, and then if you get errors it means there's a problem with the internet connection.
I wrote a jQuery plugin for doing this. By default it checks the current URL (because that's already loaded once from the Web) or you can specify a URL to use as an argument. Always doing a request to Google isn't the best idea because it's blocked in different countries at different times. Also you might be at the mercy of what the connection across a particular ocean/weather front/political climate might be like that day.
http://tomriley.net/blog/archives/111
i have a solution who work here to check if internet connection exist :
$.ajax({
url: "http://www.google.com",
context: document.body,
error: function(jqXHR, exception) {
alert('Offline')
},
success: function() {
alert('Online')
}
})
Sending XHR requests is bad because it could fail if that particular server is down. Instead, use googles API library to load their cached version(s) of jQuery.
You can use googles API to perform a callback after loading jQuery, and this will check if jQuery was loaded successfully. Something like the code below should work:
<script type="text/javascript">
google.load("jquery");
// Call this function when the page has been loaded
function test_connection() {
if($){
//jQuery WAS loaded.
} else {
//jQuery failed to load. Grab the local copy.
}
}
google.setOnLoadCallback(test_connection);
</script>
The google API documentation can be found here.
A much simpler solution:
<script language="javascript" src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
and later in the code:
var online;
// check whether this function works (online only)
try {
var x = google.maps.MapTypeId.TERRAIN;
online = true;
} catch (e) {
online = false;
}
console.log(online);
When not online the google script will not be loaded thus resulting in an error where an exception will be thrown.
EDIT 2
I still need help, as the error still isn't fixed.
Below I have added a link to a screenshot of what .ajaxError() does throw:
http://i.imgur.com/RkcgNtG.jpg
Another thought was the server setting. Is there any chance that suphp or the mpm_itk module are the cause for this bug?
EDIT
I have figured out something. My Ajax-Call should update some data from an input and a textarea. I tested some more and saw that the 403 only occurs when the value of my textarea or the value of my input has more than one whitespace ... So 'that-is-a-test' and 'thatisatest' work fine, but 'that is a text' returns a 403.
I also want to add that the Ajax-Call is done with a get-method.
Original
I've got a problem working on my cakePHP project.
First of all I have to say that I am new to cakePHP and that I work on a project that was not developed by me initially.
I have set up this project on my localhost (Windows 8 with xampp) and everything works fine.
In a next step I edited the Bootstrap-Configuration file, corrected the database information and uploaded all files to my server.
Now everything still works, except for the jQuery AjaxCalls. Tracing the root of this error I saw that the server returns an 403 Status Code.
Now I searched for possible reasons. First aspect I found was to set the security-level from high to medium. But as my 2.x project does not have this setting anymore, I need another solution.
Next step was to check the server settings. But the phpinfo of both, my local version and the server where the error takes place, seem to be nearly the same.
Only the PHP version of 5.3 on the server and the use of FastCGi are different.
But as cakePHP do not need more than 5.2 that cannot be the reason.
So now I have no idea what to search for. I think it has to be one setting because it works fine on my localhost, worked fine on another server but fails on the new server.
Any ideas I could check? As I am not an expert of server technologies it would be great if you answer as detailed as possible.
thanks and greets
I have now changed my jQuery Ajax-Call that looks like following
$.ajax({
url: '/metas/saveMetas',
data: {
"model": model,
"f_key": f_key,
"pagetitle": pagetitle,
"keywords": keywords,
"description": description,
"niceurl": niceurl
},
dataType: 'json',
complete: function(){
return false;
},
success: function(result) {
if(typeof result =='object') {
$('#modal-spinner-seo-update').hide('slow');
jQuery.each(result, function(field, message) {
$('#seo-'+field).next('div.error-message').html(message).fadeIn('fast');
});
} else {
$('#modal-spinner-seo-update').hide('slow', function() {
$("#seo-widget-message-success").fadeIn('slow').delay(2000).fadeOut('slow');
});
}
return false;
}
});
into a simple JavaScript xmlHttpRequest as following
xhr = new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if (xhr.readyState==4 && xhr.status==200)
{
console.log(xhr.responseText);
if(typeof xhr.responseText =='object') {
$('#modal-spinner-seo-update').hide('slow');
jQuery.each(result, function(field, message) {
$('#seo-'+field).next('div.error-message').html(message).fadeIn('fast');
});
} else {
$('#modal-spinner-seo-update').hide('slow', function() {
$("#seo-widget-message-success").fadeIn('slow').delay(2000).fadeOut('slow');
});
}
return false;
}
};
xhr.open('GET','/metas/saveMetas?model='+model+'&f_key='+f_key+'&pagetitle='+pagetitle+'&keywords='+keywords+'&description='+description+'&niceurl='+niceurl, true );
xhr.send();
and now everything seems to work fine. But I still do not understand why. Can anyone explain what I did wrong?
In my hydbrid app (Phonegap), I am trying to write to localStorage in a very standard way :
window.localStorage.setItem("proDB", JSON.stringify(data));
or
window.localStorage["proDB"] = JSON.stringify(data);
But it doesn't work on Safari on iPad 2 (iOS 7.1).
It doesn't work and the whole app stops.
Here's the userAgent of this ipad :
Can you help me ?
Thanks
Please check whether you have Private Browsing enabled in Safari. In Safari Private Browsing mode, you get a quota of zero. Hence, all calls to localStorage.setItem will throw a quota exceeded error. Personally I think this is a huge mistake by Safari (as so many sites break), but it is what it is so we have to find a way around it. We can do this by:
Detecting whether we have a functional localStorage
Falling back to some replacement if not.
Read on if you want the details :)
1: Detecting a functional local storage
I am currently using this code to detect whether local storage is available, and fall back to a shim if not:
var DB;
try {
var x = '_localstorage_test_' + Date.now();
localStorage.setItem(x, x);
var y = localStorage.getItem(x);
localStorage.removeItem(x);
if (x !== y) {throw new Error();} // check we get back what we stored
DB = localStorage; // all fine
}
catch(e) {
// no localstorage available, use shim
DB = new MemoryStorage('my-app');
}
EDIT: Since writing this I have packaged up the feature detecting code. If you are using NPM you can install storage-available like so:
npm install --save storage-available
then you can use it in your code like this:
if (require('storage-available')('localStorage')) {
// Yay!
}
else {
// Awwww.....
}
2. Fall back to a shim
The easiest way to deal with the issue once we have detected the problem is to fall back to some other object that does not throw errors on every write.
memorystorage is a little library I wrote that follows the Web Storage API but just stores everything in memory. Because it uses the same API, you can use it as a drop-in replacement for localStorage and everything will function fine (though no data will survive page reload). It's Open Source so use as you please.
Background info
For more information on MemoryStorage and this issue in general, read my blog post on this topic: Introducing MemoryStorage.
I have set local storage key values through below logic using swift2.2
let jsStaring = "localStorage.setItem('Key', 'value')"
self.webView.stringByEvaluatingJavaScriptFromString(jsStaring)
Your first setItem example is correct. I don't believe that you can do the second option (localStorage["someKey"] = "someValue") though. Stick with the first one.
You mention hybrid - is it a PhoneGap or some other framework? Where in the app are you calling localStorage.setItem? If PhoneGap, be sure that everything has loaded via onDeviceReady first before trying to access localStorage:
<script type="text/javascript">
// Wait for PhoneGap to load
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
function onDeviceReady() {
window.localStorage.setItem("key", "value");
}
</script>
Also, if the app freezes/stops working, in my experience it's because somewhere in the code you are accessing an object that is undefined. Perhaps try some debugging by checking if localStorage is undefined and logging it? Are you 100% sure that the "setItem" line is where it fails? Console.log is your friend, prove it! :)
if (localStorage === undefined) {
console.log("oops, localStorage not initialized yet.");
}
else {
window.localStorage.setItem("proDB", JSON.stringify(data));
console.log("localStorage available.");
}
Facebook application, how to check if inside Facebook canvas / standalone using PHP?
This question is an exact duplicate of above question, but the solution for above methods doesn't seem to work now, any updates? and regarding the HTTP_REFERRER header, i found some problems inside Firefox. Any other hacks?
Being passed a valid signed_request might be one way to test this...
Only your application with its APP_SECRET will be able to decode that signed_request so it is un-likely that someone would be able to spoof a valid signed_request; If they are able to do that - then they have pretty much bypassed Facebook security.
If they managed to do that, then maybe they deserve to be able to use your application outside of Facebook ;)
I just do this ($this <--- is a facebook sdk object):
$this->signedRequest = $this->getSignedRequest();
if(!$this->signedRequest){
show_404();
}
Try this:
public static function referrerIsFacebookCanvasApp() {
if (stripos($_SERVER['HTTP_REFERER'], "apps.facebook.com") === false || strpos($_SERVER['HTTP_REFERER'], "facebook.com/l.php?u=") !== false) {
return false;
}
return true;
}
I've a problem...I use jQuery ajax to call a web service that returns XML. The jQuery ajax stuff works awesome for every browser except for ie.
So for ie browsers, I am using XDomainRequest. Here is the code:
if ($.browser.msie && window.XDomainRequest) {
// Use Microsoft XDR
var xdr = new XDomainRequest();
xdr.open("get", theUserUrl);
xdr.timeout = 95000;
xdr.onerror = function () {
console.log('we have an error!');
}
xdr.onprogress = function () {
console.log('this sucks!');
};
xdr.ontimeout = function () {
console.log('it timed out!');
};
xdr.onopen = function () {
console.log('we open the xdomainrequest');
};
xdr.onload = function () {
// XDomainRequest doesn't provide responseXml, so if you need it:
var xml2 = new ActiveXObject("Microsoft.XMLDOM");
xml2.async = false;
xml2.loadXML(xdr.responseText);
console.log('do we get any response text at all?: ' + xdr.responseText);
ParseOwnershipObjects(xml2);
//AddServiceRequestsToMap(xml2, map, spinner);
};
xdr.send();
}
This exact code works fine elsewhere in the application with a
different url.
The url is fine, it returns exactly what it should in the browser
(and hence why the jquery ajax call works). Couple of things to
note:
I am integrating my own html/javascript with another guy's asp.net
project.
In the global.asax.cs file, I have:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
}
so I don't think that it's a header problem.
None of my handlers fire. Not the onprogress, ontimeout, onerror...nothing!
I don't have time to convert the web service to JSON.
Any thoughts?
Thanks!
Disclaimer - I actually haven't used 'XDomainRequest' - when using jQ I set data to jsonp for xdomain requests...
When debugging - are you using IE Dev tools (F12)? If not, the error is likely console.log
EDIT:
mea culpa, disregard the jsonp stuff - missed the part you mentioned XML
Update:
Out of curiosity I'm trying XDomainRequest. I copied your code and just added a value for theUserUrl.
as above/expected, unless I have Internet Explorer Developer tools running, console is undefined - and may give the impression that "none of your handlers are firing".
Once I have the IE dev tools enabled (docked or otherwise) xdr.onerror fires. we have an error is logged in the IE console. So while there is an error, the handler does fire.
A quick read on XDomainRequest requires the responding server to have the Access-Control-Allow-Origin header. I'm calling my own server and I know I don't have this header set, so without further debugging, it would be a good guess that's why xdr.onerror is being fired.
As it turns out, there were special characters in the url parameters that were not being correctly dealt with by the XDomainRequest object. Instead of the GET request, I am going to use the POST request on internet explorer-only queries.
EDIT - I ended up switching the web service over to return output in JSON format, thus negating the need for the XDomainRequest. Using JSON speeds things up a bit too, I recommend it!