Excel for Mac JS Add-in HTTP Request Timeout - javascript

I'm working on an Excel js add-in. The add-in has multiple rest api calls using ajax. One in particular can take some time to respond (in this case over 10 minutes). It is working properly in Excel Online - the response is received and displayed. Excel for Mac appears to have a timeout (or something) affecting the request after 1 minute. It's returning a status code 0 and our server is throwing a 499 (client cancelled request).
Is there a timeout in Office for Mac and, if so, is there a way to change it? Adding a timeout field to the ajax request isn't working.

I think this is the same question as Lengthy HTTP calls failing in TaskPane apps on Office for Mac Client. There is a default timeout of 60 seconds for the WebKit control Office uses. There is no way to override the default timeout from our end. I have tried the following code that works with a 10 minute request:
var xhr = new XMLHttpRequest();
var startDate = new Date();
xhr.open('POST', url, true);
xhr.timeout = 800000; // time in milliseconds
xhr.onload = function () {
console.log((new Date() - startDate) + " milliseconds to return.");
};
xhr.ontimeout = function (e) {
console.error("error");
};
xhr.send("data");
Note that there was a WebKit regression that is now fixed that broke setting the timeout property. You will need the latest version of Safari. Also, jQuery timeout property wasn't working because they are not actually setting the native XMLHttpRequest::timeout property that WebKit listens to. If you are using a third party library to make the request, make sure it sets XMLHttpRequest timeout properly.

Related

How to replace ajax with webrtc data channel

** JAVASCRIPT question **
I'm using regularly ajax via XMLHttpRequest. But in 1 case, I need 1 ajax call per seconds....
but long term wise and with growing number of simultaneous users, it could bloat easily...
I'm reading stuff about webRTC data channel and it seems interesting and promissing.
Here my working AJAX function as an example of how easy and there is a few lines of codes to communicate from the browser to the server and vice-versa
function xhrAJAX ( divID , param2 ) {
// random value for each call to avoid cache
var pcache = (Math.floor(Math.random() * 100000000) + 1);
// parameters
var params = "divID="+encodeURIComponent(divID)+"&param2="+encodeURIComponent(param2);
// setup XMLHttpRequest with pcache
var xhr = new XMLHttpRequest();
xhr.open("POST", "/file.php?pcache="+pcache, true);
// setup headers
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// prepare onready scripts
xhr.onreadystatechange = function(e) { if (xhr.readyState == 4) { $("#"+divID).html(e.currentTarget.responseText) ; } }
// send the ajax call
xhr.send(params);
}
How can I "transpose" or "convert" this ajax workflow into a webRTC data channel ? in order to avoid to setup a setInterval 1000...
Note: I mean how to replace the javascript portion of the code. PHP here is only to illustrate, I don't want to do a webRTC via PHP...
Is there a simple few lines of code way to push/receive data like this ajax function ?
the answer I'm looking for is more like a simple function to push and receive
(once the connection with STUN, ICE, TURN is established and working...)
If I need to include a javascript library like jquery or the equivalent for webRTC, I'm welcoming good and simple solution.
*** The main goal is this kind of scenario :
I have a webapp : users in desktop and users within webview in Android and IOS
right now I have this workflow => ajax every 3 seconds to "tell" the main database that the user is still active and using the browser (or the app)
But I'd like to replace with this kind : when the user uses the browser => do a webrtc data chata in background between the browser and the server
While reading on the web I think that webRTC is a better solution than websocket.
** I did a bit of search and found peerjs....
https://github.com/jmcker/Peer-to-Peer-Cue-System/blob/main/send.html
I'll do some testing, but in the meantime, if someone can trow ideas, it could be fun.
Cheers

XMLHttpRequest returning with status 200, but 'onreadystatechange' event not fired

We have been receiving an intermittent bug with the XMLHttpRequest object when using IE11. Our codebase is using legacy architecture, so this browser is required.
After clicking a button, the browser launches an out-of-band process by creating a new ActiveX control which integrates with a camera to capture an image. This control appears to be working fine... it allows the operator to capture the image, and the Base64 content of the image is returned out of the control back to the browser interface, so I think we can rule out a problem with this object.
Once the image is returned to the browser, the browser performs an asynchronous 'ping' to the web server to check if the IIS session is still alive or it has expired (because the out-of-band image capture process forbids control of the browser while it is open).
The ping to the server returns successfully (and running Fiddler I can see that the response has status 200), with the expected response data:
<sessionstate>ok</sessionstate>
There is a defined 'onreadystatechange' function which should be fired on this response, and the majority of times this seems to fire correctly. However, on the rare occasion it does appear, it continues to happen every time.
Here is a snippet of the code... we expect the 'callback()' function to be called on a successful response to Timeout.asp:
XMLPoster.prototype.checkSessionAliveAsync = function(callback) {
var checkSessionAlive = new XMLHttpRequest();
checkSessionAlive.open("POST", "Timeout.asp?Action=ping", true);
checkSessionAlive.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
checkSessionAlive.onreadystatechange = function() {
if (checkSessionAlive.readyState == 4) {
if (checkSessionAlive.responseText.indexOf("expired") != -1 || checkSessionAlive.status !== 200) {
eTop.window.main.location = "timeout.asp";
return;
}
callback(checkSessionAlive.responseText);
}
}
checkSessionAlive.send();
}
Has anyone seen anything like this before? I appreciate that using legacy software is not ideal, but we are currently limited to using it.

Why does Safari send the wrong cookie value?

I have code that regularly increments a counter in a cookie value to be sent by AJAX. This works in Chrome/FF/IE, but in Safari, the cookie value that I receive on the server is approximately the JS value + 10.
/* Example uses jQuery */
var counter = 0;
function handleInteraction(){
counter++;
createCookie("COUNTER", counter, 10);
}
$('body').on('mousemove', function () {
handleInteraction();
});
$('body').on('click', function () {
console.log(counter);
$.get("http://bryan.co.il/del.php");
handleInteraction();
});
Why is this?
Please provide documentation from Safari if you have it.
I can't find related documentation.
Safari seem to have changed the implementation of XHR requests - although this does appear to be allowed by the http specification.
Most browsers, when they send AJAX, they read the cookie value synchronously, and then send the request asynchronously.
Safari however, even reads the cookie value asynchronously (ie. whenever it wants).
Here is some code to demonstrate using createCookie from quirksmode.org:
createCookie("TEST_COOKIE", "Before", 10);
var x = new XMLHttpRequest();
x.open("GET", location.href);
x.send();
createCookie("TEST_COOKIE", "After", 10);
In Chrome (etc), the server will receive the "before" cookie. In Safari (tested on Windows, Mac & iPad), the server will receive after!

Recall Long Polling AJAX Request When it Fails/Network offline

I am implementing a successful long polling within PHP/Node.js application. I have created a routine to launch the long polling AJAX request after the waking up of the computer (after sleep mode) as below.
The problem is that the AJAX request fails due to internet connectivity as it needs some time to get ready and this leads AJAX request to fail. I need to recall this request again until the internet is back but I can't find any way to know if the previous request has failed to send new one and track its status.
I am not using the Jquery and I don't want to use it.
I am able to create a timeout for direct AJAX calls if they don't reach a server within a timeout seconds, but the long polling request status is pending at server for 40 seconds and I need to detect if it fails after 2 seconds from sending.
Is there any solution to do with xmlHTTP object?
I would greatly appreciate your help. Thanks.
var program ={
init: function(){
this.isSleep = function(lastTime){
var lastTime = lastTime;
clearTimeout(program.tt)
program.tt = setTimeout(function(){
var currentTime = new Date().getTime();
if(currentTime > (lastTime + 2000*2) ){
// request fails if the internet connection was not ready
ajax.call({ // long polling request......});
}
program.isSleep(new Date().getTime());
}, 2000);
};
this.isSleep(new Date().getTime());
}
}
Set a variable to true, then call a timer for 2 seconds. If the ajax returns turn that variable to false, if the timer is fired then check your variable and do whatever you need to do.

Intermittent Cloudfront CDN failures (monitoring) - CDN Failover

For the past 2 months I have been experiencing Amazon Cloudfront intermittent failures (2-3 times a week) whereby the page would load from my web server but all the assets from the CDN would block in pending for minutes at the time (I confirmed that with shell curl from different datacenters some work some don't depending on the edge location - London?). Once the pending requests succeed all goes back to normal.
We have been reporting this to amazon but they always reply with "Don't expect reply from us. If gazillion people will complain only then will we consider looking into this" kind of message. Often it resumes normal operation before I'm done writing the support request.
I came to a conclusion that the best way to proceed due to lack of development time for migrating to other CDN is to add a script in the html header that will let us know whenever something similar happens. So say in the header try to download a tiny gif from the CDN if the request takes longer than N msec then call an arbitrary url within the root domain (for monitoring).
The question:
How does one reliably, across all popular browsers, request a file with callback on timeout. i.e.:
request file from CDN using AJAX - will not work due to cross-domain limitations?
setTimeout("callbackTimeout",2000) callbackTimeout(){getElementById() else ...HttpWebRequest...} - would that be blocked by pending HttpWebRequest request or will it work?
How else?
Thanks.
This has been briefly tested in IE.7&8, up to date FF on Windows & OSX as well as Chrome. I suggest you test it yourself. Minify! If you know better way of doing this please suggest your improvements. The way using i.e. script instead of an image has been considered and decided against probably mostly due to my ignorance.
The next version will write a cookie on timeout and the future requests will be handled on the server side (using relative asset path). The cookie will expire after say 30 minutes. Every consecutive timeout will renew that cookie. Not sure how I'll handle the first failover. Could be a redirect (not very elegant but simple). Perhaps I will figure out smarter way (possibly more elegant but more complex too).
<script type="text/javascript">
//<![CDATA[
// Absolute path to a picture on your CDN to be monitored
cdnImagePath = "http://YOURCDNADDRESS.net/empty.gif";
//this is relative path (cross domain limitation)
//will be followed by "timeout" or "other" as a reason i.e. /cdnMonitor.php?message=timeout
cdnMonitoringPath = "/cdnMonitor.php?message=";
// Recommended 3000 for 3 second(s) timeout
cdnTimeoutMilisec = 3000;
// Set to true to be notified after timeout (provides extra information)
cdnNotifyAfterTimeout = false;
// Handler methods
cdnOK = function(){
if (!cdnTimer && cdnNotifyAfterTimeout) cdnNotify('success');
}
cdnFail = function(reason){
if (reason != "timeout") {
if (cdnTimer) clearTimeout(cdnTimer);
message = "error"
} else {
message = reason;
}
cdnNotify(message);
}
cdnTimeout = function() {
cdnTimer = false;
if (cdnImage.complete == false) {
cdnFail("timeout");
}
}
cdnNotify = function(message) {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", cdnMonitoringPath + message, true);
xmlhttp.send();
} else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
// Load test image and define event handlers
cdnTimer = setTimeout("cdnTimeout()", cdnTimeoutMilisec);
cdnImage = new Image();
cdnImage.onload = cdnOK;
cdnImage.onerror = cdnFail;
cdnImage.src = cdnImagePath + "?" + Math.floor(Math.random()*1000000);
//]]>
</script>
Also this is what I'll use for ad hoc monitoring on the server side cdnMonitor.php:
error_log(date('Y-m-d H:i:s.') .next(explode('.',microtime(1))). ' - '. $_GET['message'] . ' - '. $_SERVER['HTTP_X_REAL_IP']. ' - ' . $_SERVER['HTTP_USER_AGENT'] ."\n", 3, '/tmp/cdnMonitor.log');
You will need to change the "HTTP_X_REAL_IP" to REMOTE_ADDR or whatever suits your needs. I use reverse proxy so that's what I do.
Lastly I made some last minute changes in the post editor and might have broken something. Fingers crossed.

Categories

Resources