I use easyXDM to make cross-domain POST request and receive a response. When the request reaches a timeout, easyXDM executes the ErrorHandler function twice when I run it on Firefox. On Chrome and IE7 it works fine (i.e. just one execution). Why is that? Any ideas how can I prevent it?
Firefox version 6.0.2
EasyXDM version 2.4.15.118
Hosted on IIS
Example code (this works as described above on my computer, the "Error" alert appears twice on Firefox and once on Chrome and IE7): (obviously, the timeout is set so low so that it would always happen)
<html>
<head>
<script type="text/javascript" src="easyXDM.js"></script>
<script type="text/javascript">
var rpc = new easyXDM.Rpc({
remote: "http://myserver.com/Cors.html"
}, {
remote: {
request: {}
}
});
request = {
url: "http://myserver.com/DoSomething.aspx",
method: "POST",
timeout: 1,
data: {
SomeData: "SomeInformation"
}
};
var responseHandler = function(response) {
alert("Responded");
};
var errorHandler = function(error) {
alert("Error");
};
rpc.request(request, responseHandler, errorHandler);
</script>
</head>
<body>
</body>
This was fixed in https://github.com/oyvindkinsey/easyXDM/commit/c6da9f074606f153769d8be61aca804a02a7acb9
based on the discussion in https://groups.google.com/forum/#!topic/easyxdm/DI470RVe8hk
Related
I'm trying to implement rollbar.js to Firefox extentsion. However, there is no possibility to load it within "rollbar snippet" - it loads .js file from cdn - that's not allowed in Firefox addons.
So I reworked it and load rollbar.js from local file. This solution works in Chrome extension, however in Firefox addon I always get "Rollbar is undefined" ..
Here is the simplified code I use in poppup.html...
<script>
chrome.storage.local.get(['optins'], function(value) {
var rollbarOptIn = true;
window._rollbarConfig = {
accessToken: "xxx",
captureUncaught: true,
captureUnhandledRejections: true,
enabled: rollbarOptIn,
payload: {
environment: "{{ ENVIRONMENT }}",
client: {
source_map_enabled: true,
code_version: "{{ VERSION }}",
guess_uncaught_frames: true
}
}
};
});
</script>
<script type="text/javascript" src="scripts/rollbar.js" async="false"></script>
<script>
/* ugly workaround with set timeout... */
setTimeout(function(){
...
Rollbar.error("test");
...
}, 600);
</script>
I am in the end.. please help.
Since chrome.storage is asynchronous its callback runs after rollbar.js so you probably have a browser-specific race condition between an asynchronous initialization in rollbar and that callback.
Remove <script> from your HTML and try loading it dynamically, then use its onload event:
chrome.storage.local.get('optins', ({optins}) => {
window._rollbarConfig = {
// ...............
};
const el = document.createElement('script');
el.src = 'scripts/rollbar.js';
el.onload = useRollbar;
document.documentElement.appendChild(el);
});
function useRollbar() {
Rollbar.error("test");
// ...............
}
I have a specific issue with the Geolocation api. This is my scenario:
User landed on a page ( in Chrome - Android ) with GPS location disabled.
There is a button on the page, and onClick of the button triggers the Geolocation.getCurrentPosition
Geolocation goes to the error callback with error message “User denied Geolocation”
User goes to Android settings ( mostly in notification drawer ) and turn on the location
User click the button again ( at this time, location is available ) to get the coordinates
However, Geolocation api still throws the error “User denied Geolocation”
—
At this time, the geolocation request will work only if the user refreshes the page and press the button ( note: the location is still enabled )
Is there a way to make this work without the browser refresh ?
Here is the jsbin link: https://output.jsbin.com/pihenud
Finally, I was able to solve this problem using an iFrame hack.
Here is the solution:
Instead of asking the permission in the main window, create an iFrame dynamically and call the geolocation.getCurrentPosition inside it. Now, we can use the window.postMessage to pass the position data to the parent browser window.
When we have to retry the geolocation request again, we just need to reload the iframe -- This will have the new site settings.
Here is the iframe code if anyone wants to try:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Namshi Geolocation</title>
</head>
<body>
<script type="text/javascript">
var sendMessage = function(result){
window.postMessage(JSON.stringify(result), window.location.origin);
};
var triggerGeolocationRequest = function(){
var options = {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
};
var result;
if(window.navigator.geolocation){
window.navigator.geolocation.getCurrentPosition(function(position){
var result = {
type: 'success',
data: {lat: position.coords.latitude, lng: position.coords.longitude}
};
sendMessage(result);
}, function(err){
var result = {
type: 'error',
data: { message: err.message, code: err.code }
};
sendMessage(result);
}, options)
} else {
result = {
type: 'error',
data: { message: 'No Geolocation API' }
};
sendMessage(result);
}
};
window.addEventListener('load', triggerGeolocationRequest);
</script>
</body>
</html>
And in your application code, you can have a utility to inject the iFrame. See the below code:
utils.getCurrentPosition = function(){
return new Promise(function(resolve, reject){
var ifr = document.createElement('iframe');
ifr.style.opacity = '0';
ifr.style.pointerEvents = 'none';
ifr.src = location.origin + '/geo.html'; // the previous html code.
document.body.appendChild(ifr);
ifr.contentWindow.addEventListener('message', function(message){
message = JSON.parse(message.data);
if(message.type === 'success'){
resolve(message.data);
} else {
reject(message.data);
}
document.body.removeChild(ifr);
});
});
};
I got this piece of cake function:
$.ajax({
url: 'Example.html',
DataType: 'text',
cache: false,
success: function (){
alert ('Yes');
},
error: function (){
alert ('No');
}
});
This function, works just fine, BUT ONLY FOR THE VERY FIRST TIME), from the second time on, the function sends the following error to Chrome:
GET http://MyServer.com/Example.html?_=1406469092100 net::ERR_FAILED
The same situation happens equally with this second JS option:
function doesConnectionExist() {
var xhr = new XMLHttpRequest();
var file = "http://www.example.com/Example.html";
var randomNum = Math.round(Math.random() * 10000);
xhr.open('HEAD', file + "?rand=" + randomNum, false);
try {
xhr.send();
if (xhr.status >= 200 && xhr.status < 304) {
alert ('Yes');
} else {
alert ('No');
}
} catch (e) {
alert ('No');
}
}
1) In the Ajax scenario I just indicate cache: "false"!
2) In the JavaScript scenario I am using random arguments to avoid cache!
Is there anything I am missing? in the Server side??
Please help...
It may be a server problem? I have created a jsFiddle and it seems to work like it should. I wrapped your $.ajax method in a ping function and run it 3 times fetching a jsfiddle resource.
function ping(i) {
$.ajax({
url: '/img/logo.png',
success: function () {
screen.log({text: 'attempt #'+(i+1)+ ' Yes', timed: +i, clear: 'no'});
},
error: function (d){
screen.log({text: 'attempt #'+(i+1)+ ' Nope', timed: +i, clear: 'no'});
}
});
}
See the already mentioned jsFiddle for output
Note: in your second code snippet your supply false as the third paramater to the open method, which means asynchronous = false, so the XHR there is synchronous. The cache: false parameter in the first snippet appends a random reuqeststring to the request. This prevents the browser from caching the fetched resource. I suppose it's not really necessary here.
After hours and hours of try an error I found the Answer....dedicated for those guys who are facing the same problem I did:
In my case this was not a common Web Page, it was an "Offline Web Page" with a Manifest File in it.
Simply in the section "NETWORK" of the manifest file included the file "Example.html" and that's it.
That's all folks!
So I installed the plugin for phonegap to run google analytics. I set it up using plugman, no issues. However I am unable to establish a connection to google analytics.
document.addEventListener("deviceready", function(){
console.log('device ready');
config.gaPlugin = window.plugins.gaPlugin;
config.gaPlugin.init(console.log('ga plugin inititalized'), console.log('ga plugin failed'), config.analyticsCode, 1);
}, false);
And Instead of getting a connection back I get one response of
W/GAV2(12581): Thread[WebViewCoreThread,5,main]: Need to call initialize() and be in fallback mode to start dispatch.
I thought the init function was the initialize? However as I set it every 5 seconds the connection gets refused.
W/GAV2(12581): Thread[GAThread,5,main]: Connection to https://ssl.google-analytics.com refused
W/GAV2(12581): Thread[GAThread,5,main]: Exception sending hit: HttpHostConnectException
I have no idea what to do next, I've seen reference of needing to modify the errorhandling calls to not look for an https request, but I would like to hope its just an error in my code or a configuration error. Anyone have insight?
I use the following code which works with GAPlugin
gaInit: function() {
gaPlugin.init(gaSuccessConnect, gaFail, "UA-XXXXXX-3", 10);
},
gaSuccess: function() {
console.log('Successfully connected to Google Analytics');
},
gaSuccessConnect: function() {
console.log('Successfully initiated connection to Google Analytics');
gaTrackPage();
},
gaFail: function() {
console.warn("Failed to connect to Google Analytics");
},
gaTrackPage: function() {
gaPlugin.trackPage(gaSuccess, gaFail, "index.html");
console.log('Tracking index');
},
gaTrackPageView: function(page) {
var index = "index.html";
var trackpage = index.concat(page);
console.log('Tracking ' + page);
gaPlugin.trackPage(gaSuccess, gaFail, trackpage);
},
and call gaInit from onDeviceReady.
I got strange behavior when I tried to test my
"navigator.geolocation.getCurrentPosition" web page. Here is my
testing result and code:
my code:
function detectLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(geocodePosition, onError, { timeout: 30000 });
navigator.geolocation.watchPosition(watchGeocodePosition);
}
else
{
onError();
}
}
this function was run when "body" onload event was called. I had tried to change the timeout to 10000 and 20000, but I still got same result. I also allowed crome and firefox to get my location.
result:
Using chrome (v 17.0.963.79 m), result always went to onError
function when navigator.geolocation.getCurrentPosition was called.
Using Firefox (v 10.0.2), result always went to onError function
when navigator.geolocation.getCurrentPosition was called.
Using IE (v 9), result was fantastic, I got my current location.
can anyone help me in this strange situation? I really didn't have any idea to solve this problem and I was in hurry on my project deadline. Thanks before.
EDIT :
For this couple days I got some progress, the error code code is 2 with a message "Network location provider at 'https://maps.googleapis.com/maps/api/browserlocation/json?browser=chromium&sensor=true' : Response was malformed". Still unsolved, does anyone know how to solve this?
I simulated this problem and found that the success callback functions were only called when the html page was hosted on a web server and not when opened from a filesystem.
To test I opened the file directly from my C: drive and it the callbacks didn't work and then hosted the file on Internet Information Services (IIS) and the callbacks did work.
<html>
<body onload="detectLocation()">
<!-- This html must be hosted on a server for navigator.geolocation callbacks to work -->
<div id="status"></div>
<script type="text/javascript">
function detectLocation()
{
log("detectLocation() starting");
if (navigator.geolocation)
{
log("navigator.geolocation is supported");
navigator.geolocation.getCurrentPosition(geocodePosition, onError, { timeout: 30000 });
navigator.geolocation.watchPosition(watchGeocodePosition);
}
else
{
log("navigator.geolocation not supported");
}
}
function geocodePosition(){
log("geocodePosition() starting");
}
function watchGeocodePosition(){
log("watchGeocodePosition() starting");
}
function onError(error){
log("error " + error.code);
}
function log(msg){
document.getElementById("status").innerHTML = new Date() + " :: " + msg + "<br/>" + document.getElementById("status").innerHTML;
}
</script>
</body>
</html>
I also got this message:
message: "Network location provider at 'https://www.googleapis.com/' : Returned error code 404.", code: 2
I could solve it by switching on my wifi adapter
I had the same issue. Chrome browser wan not returning a position on 30000 miliseconds timeout. Firefox was not returning a position too. I added the option enableHighAccuracy and set it to false but nothing changed(false is the default option). When i change it to true then geolocation started working!
This is my final code,
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
// Get current cordinates.
positionCords = {"lat": position.coords.latitude, "lng": position.coords.longitude};
},
function(error) {
// On error code..
},
{timeout: 30000, enableHighAccuracy: true, maximumAge: 75000}
);
}
You need to be using https, not http.
The Chrome reference for this is here - https://developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only
I know this is old topic but recently I had this error also:
message: "Network location provider at 'https://www.googleapis.com/' : Returned error code 404.", code: 2
The fix is to get api key for google maps and use it in your code
<script src='https://maps.googleapis.com/maps/api/jscallback=initMap
&signed_in=true&key=YOUR-API-KEY' async defer></script>
Here you can get API KEY: https://developers.google.com/maps/documentation/javascript/get-api-key#key
I had same issue and solution was to increase the timeout duration as mobile network are slower than wired network
{timeout: 30000, enableHighAccuracy: true, maximumAge: 75000}
along with enabling cellular positioning
In the Device Settings turn on "Wifi and Cellular positioning" option.
This will print the Latitude and Longitude of your Location
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script>
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
alert("Geolocation is not supported by this browser.");
}
}
function showPosition(position) {
document.getElementById('idLatitude').value = position.coords.latitude;
document.getElementById('idLongitude').value = position.coords.longitude;
}
</script>
</head>
<body onload="getLocation()">
<form action="HelloWorld" method="post">
<input id="idLatitude" type="text" name="strLatitude">
<input id="idLongitude" type="text" name="strLongitude">
</form>
</body>
</html>