Outlook error: "Add-in still working" when sending message - javascript

I've made a simple enough owa addin that, when the user launches it, a dialog window is opened (Office.context.ui.displayDialogAsync) where the user can modify certain aspects of the message (affects recipients and mail headers). As far as i can tell, all the async requests complete nearly instantly when the user closes the dialog and the add-in completes its work, but the error is still triggered when attempting to send.
What seems to be the cause is that when the dialog is opened, owa starts spamming requests every second or so to an address that does not exist, and the error occurs until several minutes later the requests stop in what seems like a timeout of sorts.
My developer console is filled with this;
aria-web-telemetry.js:1 POST
https://browser.pipe.aria.microsoft.com/Collector/3.0/?qsp=true&content-
type=application%2Fbond-compact-binary&client-id=NO_AUTH&sdk-version=AWT-Web-
JS-1.1.1&x-apikey=db334b301e7b474db5e0f02f07c51a47-a1b5bc36-1bbe-482f-a64a-
c2d9cb606706-7439&client-time-epoch-millis=1532959882460 404 (Not Found)
So far google has not found me anything helpful, and i just cannot comprehend why Microsoft would be calling home to an address that doesn't exist.
Sure enough, https://appsforoffice.microsoft.com/lib/1/hosted//ariatelemetry/aria-web-telemetry.js contains that url hardcoded. What can i do?
edit 1)
I'm hosting my own trial windows server on a virtual machine, and using the exchange accounts of that server.
The error occurs on all browsers.
Firefox gives me Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://browser.pipe.aria.microsoft.com/Collector/3.0/?qsp=true&content-type=application%2Fbond-compact-binary&client-id=NO_AUTH&sdk-version=AWT-Web-JS-1.1.1&content-encoding=base64&x-apikey=a387cfcf60114a43a7699f9fbb49289e-9bceb9fe-1c06-460f-96c5-6a0b247358bc-7238&client-time-epoch-millis=1532965578192. (Reason: CORS request did not succeed).
IE does not really give me anything i can pick out
The example above was from chrome
I have not installed it on desktop, so only web so far.
As for code.
My manifest defines an action for a button control
<Action xsi:type="ExecuteFunction">
<FunctionName>showMessageSecurityDialog</FunctionName>
</Action>
that function in turn shows the dialog
Office.context.ui.displayDialogAsync(window.location.origin + dialogPage, { height: 50, width: 75, displayInIframe: true }, dialogCallback);
On the dialog, when the user presses the save button it runs
Office.context.ui.messageParent(true); to signal we're done
from here
dialog = asyncResult.value;
dialog.addEventHandler(
Microsoft.Office.WebExtension.EventType.DialogMessageReceived,
messageHandler
);
dialog.addEventHandler(
Microsoft.Office.WebExtension.EventType.DialogEventReceived,
eventHandler
);
is called, which neatly flows into the message handler
dialog.close();
if (arg.message == true) {
applyMessageSecurity();
}
applyMessageSecurity in turn runs a whole lot of async requests, and when the promises of those requests are resolved, i let the user know with Office.context.mailbox.item.notificationMessages.addAsync("information", {type: "informationalMessage", persistent: false, message: "success"})
afaik we should be done at this point. All the code is done running, the dialog is closed, yet, something in the background is still on causing owa to think the addin is running

Please ensure to call event.completed() after dialog closing or where your code finishes all of its work so that outlook can be notified that the current uiless code has been completed. You can find more details in this article.

Related

How to call API only when user reload/leave site from the browser alert and not on click of cancel?

I am trying to do an API call when the user is trying to close/reload the browser/tab. I don't want to call the API if the user clicks on cancel. I followed JavaScript, browsers, window close - send an AJAX request or run a script on window closing, but it didn't solve my issue. I followed catching beforeunload confirmation canceled? for differentiating between confirm and cancel. I have no idea how to make the API call when the user reloads/closes the browser and not to call the API when user clicks on cancel. I followed JavaScript, browsers, window close - send an AJAX request or run a script on window closing and tried like
For showing alert on reload or close the tab
<script>
window.addEventListener("onbeforeunload", function(evt){
evt.preventDefault()
const string = '';
evt.returnValue = string;
return string;
})
</script>
and on click of cancel, nothing should happen. If the user is forcefully closing the browser or reloading, the API should be called
<script type="module">
import lifecycle from 'https://cdn.rawgit.com/GoogleChromeLabs/page-lifecycle/0.1.1/dist/lifecycle.mjs';
lifecycle.addEventListener('statechange', function(event) {
if (event.originalEvent === 'visibilitychange' && event.newState === 'hidden') {
var URL = "https://api.com/" //url;
var data = '' //payload;
navigator.sendBeacon(URL, data);
}
});
</script>
But it's not happening. Any help is appreciated. Thanks
Your problem is happening because you're using beforeunload to present a prompt.
I can see that you're handling the beforeunload event properly, so you must already be aware that browser vendors have deliberately limited the ability of script authors to do custom stuff when the user wants to leave the page. This is to prevent abuse.
Part of that limitation is that you don't get to find out what the user decides to do. And there will not be any clever workarounds, either. Once you tell the browser to present the beforeunload prompt, you lose all your power. If the user clicks the Okay button (i.e. decides to leave the page), the browser will refuse to run any more of your code.
Presenting the prompt creates a fork in the road that you are prevented from observing. So, put a laser tripwire there instead of a fork:
window.addEventListener("onbeforeunload", function(evt) {
navigator.sendBeacon(url, payload)
})
This is guaranteed to run when the user actually leaves the page, and only when the user actually leaves the page. But, you sacrifice the ability to try to talk the user out of leaving. You can't have it both ways.
You can't always get what you want, but if you try, sometimes you just might find you get what you need. -- The Rolling Stones
I can only think of one way to accomplish what you need, but it requires help from the server. This is not an option for most people (usually because the beacon goes to a third-party analytics provider who won't do this), but I'm including it here for completeness.
before the beforeunload handler returns, fire a beacon message that says "user is maybe leaving the page"
after firing that beacon, and still before returning, set up a document-wide mousemove handler that fires a second beacon message that says "the user is still here" (and also de-registers itself)
return false to present the prompt
modify your server so that it will reconcile these two events after some kind of delay:
if the server receives beacon 1 and then also receives beacon 2 (within some reasonably short time-frame, e.g. 5 minutes), it means the user tried to leave but then changed their mind, and so the server should delete the record of beacon 1
if the server receives beacon 1 but doesn't receive beacon 2 within the time-frame, then it means the user really did leave, and so the server would rewrite the previous beacon datapoint to say "user actually departed"; you wouldn't need to actually write beacon 2 to your datastore
(Or, depending on expected traffic and your infrastructure, maybe the server just holds the beacon 1 datapoint in RAM for the 5 minutes and commits it to your datastore only if beacon 2 never shows up. Or you could write both beacons to the database and then have a different process reconcile the beacons later. The outcome is identical, but they have different performance characteristics and resource requirements.)
P.S.: Never use "URL" (all caps) as a variable name in javascript. "URL" is actually a useful web API, so if you use that exact variable name, you're clobbering a useful ability. It's just like if you did let navigator = 'Henry'. Yes, it will execute without error, but it shadows a useful native capability.

launchWebAuthFlow callback does not run, and the Chrome extension window closes immediately?

I am using chrome.identity.launchWebAuthFlow to retrieve an authentication code from my Rails app which is set up as an OAuth2 provider using the Doorkeeper gem (the Doorkeeper side of things is working).
So I send then request to my server with this method from the Chrome extension:
requestGrant: function(){
chrome.identity.launchWebAuthFlow(
{
'url': authService.grantEndPoint(),
'interactive': true
}, function(redirect_url){
/* Extract auth code from redirect_url */
var code = authService.extractCode(redirect_url);
alert(code);
authService.getAccessToken(code);
}); //launchWebAuthFlow ends here
}
And my server receives the request and redirects to
https://<my_chrome_extension_name>.chromiumapp.org/oauth2?code=<access_code_generated_by_oauth>
with a 302 found.
But, the Chrome extension immediately closes, and the callback function of launchWebAuthFlow does not run. I know it is not running because I call alert() in the callback (doesn't run), and make another request to my server for the access token (server does not receive the request).
I think part of the problem is that the chrome extension might be closing right when launchWebAuthFlow is called, because the window launchWebAuthFlow opens is a web view of the servers authorization flow, and the extension closes (or is the auth flow just being displayed through the extension?)
For some reason launchWebAuthFlow's default behavior is to close the window according the documentation, but the callback still isn't running.
How can I get the callback function to run, and prevent the chrome extension window from closing?
I was running the launchWebAuthFlow in non background script. I moved the auth logic to a background script and it works fine.
I too was experiencing almost the same issue. I was trying to launch the webauthflow from my popup.html but the popup.html would close once the auth flow began, aborting the code that would execute upon succesful return of a token.
My suggestion is to instead take care of authentication in options.html.
(https://developer.chrome.com/extensions/optionsV2)
This will launch a popup modal that stays open even after your auth flow opens, (as opposed to popup.html closing when it loses focus), meaning the rest of your code will execute.
Hope this helps.

SignalR & IE Issue - poll is pending

I have a Problem With IE and SignalR, I'm using the it to perform a Syncing action between two databases, the Actions Completed successfully on Google Chrome / Firefox / Safari in all scenarios.
Using IE for the First time the sync performed successfully but only for one time, in the second time a pending request stack and the page stay freeze for ever.
I found a solution online which is changing the transport mode.
But page still freezing.
if (isIE()) {
$.connection.hub.start({ transport: ['serverSentEvents','foreverFrame']}).done(function () {
progressNotifier.server.DoMyLongAction();
});
}else{
$.connection.hub.start({ transport: ['serverSentEvents','longPolling'] }).done(function () {
progressNotifier.server.DoMyLongAction();
});
}
I'm Using:
SgnalR v2.1.0.0
.Net framework v4.5
jquery v1.8
is it an Issue or I'm Doing something wrong ?
Edit
my application use Jquery progress bar and i Update this progress bar using this Code:
server side:
Clients.Caller.sendMessage(msg, 5, "Accounts");
client side:
progressNotifier.client.sendMessage = function (message, value, Entity) {
pbar1.progressbar("value", nvalue);
};
it's working on Firefox so I thought it's a signalR Issue !! Now i became confused if it's working as expected then what causes this problem ?
you can try use EventSource (SSE).
I am using this:
https://github.com/remy/polyfills/blob/master/EventSource.js
but modified, for SignalR:
http://a7.org/scripts/jquery/eventsource_edited.js
I am working with it for one year, SignalR just check for window.EventSource and it works.
The solution you found online is not likely to help your issue.
I doubt your IsIE() function is correctly identifying IE. If it was, SignalR should only be attempting to establish a "foreverFrame" connection, since IE does not even support "serverSentEvents". I would not expect IE to make any "/signalr/poll" requests, because those requests are only made by the "longPolling" transport.
Also, having a "pending" poll request in the IE F12 tool's network tab is entirely expected. This is how long polling is designed to work. Basically, as soon as a message is received the client makes a new ajax request (a long poll) to retrieve new messages. If no new messages are immediately available, the server will wait (for up to 110 seconds by default in the case of SignalR, not forever) for a new message to be sent to the client before responding to the pending long poll request with the new message.
Can you clarify exactly what issue you are having other than seeing a pending poll request showing up under the network tab? It would also help if you you enabled tracing in the JS client, provided the console output, and showed all the "/signalr/..." requests in the network tab.

How to prevent my browser from showing "waiting for MyHostName" message during ajax Post/Get operation?

When you open a site with Chrome it shows a message in status bar telling "Waiting for MyHost name" plus it shows Ajax Loader circle in the caption of the tab. Now I have the following javascript function:
function listen_backend_client_requests() {
$.get('/listen?cid=backend_client_requests', // an url to nginx http push channel, http connection stays opened for a long time until the actual data starts to arrive
{},
function(r) {
alert('check');
if (r == 'report_request') {
report_request();
}
listen_backend_client_requests();
}
, 'json');
}
The "$.get(...)" operation is "long polling"(via nginx http push module). It doesn't receive data instantly but waits until the data is published to a channel. And during all this time (may take up to 15 minutes) Chrome shows 'waiting for My host name' in the lower left part of the window and also shows Ajax Loader circle. I dont want them to be shown not in Chrome but neither in any other browser and I have no idea how to do that...
P.S.
By the way, I know that google docs are using the same scheme, but some how their site causes the browser not to show the message. Any suggestions?
Have you tried setting window.status? Although I'm not sure I would recommend it, it probably would do what you want. Just be sure to reset the status when appropriate.
I've found solution to my problem in contrast to the following posts
How do I implement basic "Long Polling"?
Sending messages to server with Comet long-polling
Browers entering "busy" state on Ajax request
my problem was that I was starting the long poll ajax request before my page was actually loaded and this fact prevented browser from "waiting for" state...
Just start your long polling process after you have your page completely loaded...

IE hang for 5 minutes when calling synchronous xmlhttprequest

I have a web application and use ajax to call back to my webserver to fetch data.
Sometimes(at rather unpredictable moments, but it can be reproduced) IE hangs completely for 5 minutes(the window says Not Responding) and then comes back and the xmlhttprequest object responds with error 12002.
The way I can reproduce it is as follows.
Open window(B) from main window(A) using button
Window A calls synchronous ajax(PROC1) when button is clicked to open window B. PROC1 Runs file.
New window(B) has ajax code(PROC2) and calls server asynchronous. Runs fine
User closes Window B after PROC2 completed but before data is returned.
In Main Window(a) user clicks button again. PROC1 runs again but now the send() call blocks for 5 minutes.
Please help. I've been looking for 3 days.
Please note:
* I can't test it in firefox (the app is not firefox compatible)
* I have to use synchronous calls (that's the way the app is constructed and it would take too much developer effort to rewrite it)
Why does this happen and how to I fix this?
You're right Jaap, this is related to Internet Explorer's connection limit of 2. For some reason, IE doesn't release connections to AJAX requests performed in closed windows.
I have a very similar situation, only slightly simpler:
User clicks in Window A to open Window B
Window B performs an Ajax call that takes awhile
Before the Ajax call returns, user closes Window B. The connection to this call "leaks".
Repeat 1 more time until both available connections are "leaked"
Browser becomes unresponsive
One technique you can try (mentioned in the article you found) that does seem to work is to abort the XmlHttp request in the unload event of the page.
So something like:
var xhr = null;
function unloadPage() {
if( xhr !== null ) {
xhr.abort();
}
}
Another option is to use synchronous AJAX calls, which will block until the call returns, essentially locking the browser. This may or may not be acceptable given your particular situation.
// the 3rd param is whether the call is asynchronous
xhr.open( 'get', 'url', false );
Finally, as mentioned elsewhere, you can adjust the maximum number of connections IE uses in the registry. Expecting visitors to your site to do this however isn't realistic, and it won't actually solve the problem -- just delay it from happening. As a side-note, IE8 is going to allow 6 concurrent connections.
Thanks for answering Martijn.
It didn't solve my issues. I think what I'm seeing is best described on this website:
http://bytes.com/groups/javascript/643080-ajax-crashes-ie-close-window
In my situation I have an unstable connection or a slow webserver and when the connection is too slow and the browser and the webserver still have a connection then freezes.
By default Internet Explorer only allows two concurrent connections to the same website for download purposes. If you try and fire up more than this, I.E. stalls until one of the previous requests finishes at which point the next request will complete. I believe (although I could be wrong) this was put in place to prevent overloading websites with many concurrent downloads at a time. There is a registry hack to circumvent this lock.
I found these instructions kicking around the internet which alleviated my problems - I can't promise it will work for your situation, but the multi-connection limit you're facing appears related:
Click on the Start button and select Run.
On the Run line type Regedt32.exe and hit Enter. This will launch the Registry Editor
Locate the following key in the registry:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
Click on the Internet Settings Key.
Now go to the Edit menu, point to NEW
click DWORD Value
Type MaxConnectionsPer1_0Server for the name of this DWORD Value.
Double-click on the MaxConnectionsPer1_0Server key you just created and enter the following information: Value data: 10. Base: Decimal.
When finished press OK.
Repeat steps 4 through 9. This time naming the key MaxConnectionsPerServer and assigning it the same values as indicated in Steps 8.
When finished press OK
Close the Registry Editor.
Of course, I would use these in conjunction with the abort() call previously mentioned. In tandem, they should fix the issue.
IE5 and IE6, indeed, do hang when attempting to receive data from a PHP script. The reason is that these browsers can not decide when has all of the data been received and the connection can be closed. So they wait until connection expires (thus the 5 or 10 minute hang). A way to solve this is to tell to the browser how much data it will receive. In PHP you can do that using output buffering, for example as follows:
ob_start();
echo $html_content;
header( 'Connection: close' );
header( 'Content-Length: '.ob_get_length() );
flush();
ob_end_flush();
This is a solution when one is just loading a normal web page. When one is using
AJAX GET via Microsoft.XMLHTTP object it is enough to
send the "Connection: close" header with the GET request, like
r.request.open( "GET", url, true );
r.request.setRequestHeader( "Connection", "close" );
r.request.send();
Winsock Error 12002 means the following according to msdn
ERROR_INTERNET_TIMEOUT
12002
The request has timed out.
Winsock is the underlying socket transfer object for XMLHTTP in IE so any error thats not in the HTTP error range (300,400,500 etc) is almost always a winsock error.
What wasnt clear from your question is wheter the same resource is being queried the 2nd time round. You could force a new uncached resource by appending:
'?uid=+'Math.random()
To the URL which might solve the issue.
another solution might be to attach a function to the "onbeforeunload" event on the window object to call abort() an any active XMLHTTP request just before the window B is closed.
Hope these 2 pointers solve your bug.
All these posts - Disable PDF reader.. and that stuff... will not resolve your problem...
But sure shot is - RUN WINDOWS UPDATE .. keep uptodate.. This issue gets resolved by itself..
Experience speaks ;)
HydTechie

Categories

Resources