I have a WCF service which takes a long time to process the first time it is called, and then caches those results in HttpRuntime.Cache. In order to initialize this cache I'd like to trigger a fire-and-forget ajax call from javascript.
Right now I have this javascript in the page:
$.ajax({
type: 'GET',
url: getServiceURL() + 'PrimeCacheAjax',
contentType: 'application/json; charset=utf-8'
});
Where the PrimeCacheAjax function just performs a dummy call to populate the cache.
The only issue with this approach is that the page with this ajax call is a type of landing page which executes some javascript, opens another window and closes itself. When the window closes itself before the server responds, I see a cancelled request in fiddler. I am concerned that this may lead to situations where the ajax call may not reach the server, is this possible?
Is there a way to specify (using $.ajax()) that no response will be coming, or does it not really matter?
Only time it will matter is if the request to the server is not complete. You should check to make sure the call is at a readyState value of 2 [aka sent], before exiting.
I would just perform a call with no callback, I don't believe there is a property that allows the F&F method.
for a very short ajax call you could try the following code as an alternative, if you wanted.
$.get('URL');
Related
I am building a web app and one of the functionalities is to trigger an action in the backend which can take up to 5 minutes. This 'action' is a process which will run totally on its own (regardless of the front-end/back-end of my web app).
There is a form on the client-side which I use JavaScript to grab the data, clean it up/validate and send an Ajax call to my backend to start the process (which can take up to 5 minutes).
My question is, what if the user refreshes the page? The backend will still be triggered and run on its on, but I wanted to be able to capture the response back to the browser once the process is done in the back end. Is that viable/possible?
My Ajax is a pretty simple POST request to my backend:
$.ajax({
type: 'POST',
url: '/add-user',
data: {'data': JSON.stringify(data)},
//contentType: 'application/json;charset=UTF-8',
success: function(response){
console.log(response['message'])
}
//timeout: 3000 // sets timeout to 3 seconds
});
Please refer to this question prompt-user-before-browser-close
The only solution is to display a loading bar or spinner on the page while your page is waiting for the server task to finish.
If the user wants to navigate away you can use the confirm prompt.
I highly suggest using a websocket connection and if the user really closes, then inside window.onbeforeunload you should send a message and notify the backend to cancel the request context and stop the task from running. Running something like this without this protection can make your backend easy to get bombed.
PS. If it's a process independent of your backend then you should have scripts in place to kill it if the request context is canceled.
I have two script tags on page, each containing a document.ready(), and each of them is making an ajax call to a page method.
First one loads the values into the select list. Second one loads the tree into the DOM.
<script>
$(document).ready(function() {
$.ajax({
url: 'PageMethods.aspx/GetTop50',
async: true,
success: function(data) {
//loads the values to the select list
}
//rest of stuff...
});
})
</script>
<script>
$(document).ready(function() {
$.ajax({
url: 'Default.aspx/GetTree',
async: true,
success: function(data) {
// loads the tree into DOM
}
//rest of stuff...
});
})
</script>
Why does my GetTree page method keep executing only AFTER the success callback of the GetTop50? I set the breakpoint to GetTree method serverside, and it is only hit AFTER the select list is loaded.
The client will start both ajax calls one after the other so that they are both "in-flight" at the same time. It will then be up to the server which one will complete first and depend upon how the server is configured (will it process multiple requests at once) and will depend upon what each request is doing.
If your server only handles one request at a time or if it blocks on some shared resource such as a database, then it will likely return the first request it received before returning the second request result - though that's just a likely option, certainly not a guaranteed option. For example, if the first request pretty much always takes longer to process than the second and they aren't both contending for the same shared resource, then the second request might finish first and return its results first.
It is also possible that the requests will return in a random order such that sometimes one will return first and sometimes the other will return first. As I said earlier, it all depends upon how the server processes each request and which one it finishes first.
Also, keep in mind that client-side JS is single threaded so when you are sitting at a client-side JS breakpoint somewhere, other JS cannot run until the current JS thread of execution has finished. As for the behavior in breakpoints on the server-side, that all depends upon what the server execution environment is and how it works during a breakpoint.
If you want to debug timing-related things, a breakpoint is NOT a reliable way to test things because hitting the breakpoint itself can very easily affect the behavior. Instead, you should use logging with accurate timestamps to study the exact sequence of events.
I want to thank everyone for the input, especially #jfriend00, and post the exact solution to my problem.
So the problem was that Default.aspx accesses Session, and had EnableSessionState="True" page directive.
When this directive is set, requests are sequentialized on the server side.
I solved it by moving my method into another page, that doesnt use the session state.
this is a interesting problem.
i am doing an asynchronous ajax put
return $.ajax({
url: url,
type: 'PUT',
contentType: 'application/json; charset=utf-8',
async: true, // default
success: function (result, textStatus, xhr) {...}
this works as expected, unless a user does a put before previous call returns (even though it's async, the call does take .5 second to complete)
if a user presses the button a few times (executing multiple puts) the following happens:
i see only one server call in fiddler
success gets fired for every click
all callbacks get the same new row ID (returned by the server)
this leads me to inevitable conclusion that the first server callback triggers all outstanding callbacks..
i could disable the button until the callback returns, but is it possible to handle multiple outstanding calls? is this a browser limitation? best way to handle this?
UPDATE
as a test i switched to using POST instead of PUT: adjusted type: 'POST' on JS side, and [HttpPost] on web api (server side).
the behavior did not change.
UPDATE
looking at posts like this one.. this really should work. i don't see any specific reason why the rest of concurrent requests are not not making it out to the server.
Shouldn't PUT requests be idempotent? That is, submitting multiple requests should generate the same response? If so, the code may simply be trying to coalesce your identical PUT requests since they should all end up with the same result. If you're incrementing some ID for every post (i.e. changing server state) then you should be using POST instead of PUT.
This may not fix your issue; it's just a thought.
You can't wait for an async callback in javascript. You have to restructure your code to do all future work based on the async response from the actual callback.
If you need to make multiple consecutive ajax calls, then you issue the first one and in the success handler or response handler for the first ajax call, you issue the second ajax call and in the response handler for the second one, you carry out whatever you want to do with the data
I noticed that when a link on the page has JS onclick function and also a MVC action method, the JS function fires before the action.
Wondering is this always the case?
Why/how browsers deside to run JS and the the backend method?
Can I run backend method first, but still want to fire the JS function?
Regards
Wondering is this always the case?
Why/how browsers deside to run JS and the the backend method?
Client-side JavaScript runs on the client, inside a page. Server-side .NET code runs on the server and generates an HTML document (or other resource).
To run server side code, the browser has to make an HTTP request.
The easiest way to make an HTTP request is to leave the current page and load a new one from the server (by following a link or submitting a form).
Since client-side JavaScript runs in a page, it can't run after the browser has left the page it runs in.
Can I run backend method first, but still want to fire the JS function?
You can make an HTTP request from JavaScript (before doing other JS actions) instead of leaving the current page. This is usually done with the XMLHttpRequest object and is known as Ajax.
Why/how browsers deside to run JS and the the backend method?
server side code will need a request to return the response. HTTP works on Request and Response architecture. basically client make requests in order to get the response (i.e results or desired data)
wheenever you do postback or return true to the server, it will execute server side methods.
ClickHereToSee
here return value which is returned by the function, if you return the true value it will go to the server method, if you returned the false it will prevent the default action.
Can I run backend method first, but still want to fire the JS function?
You can. use Ajax. basically Ajax requests are XMLHTTPRequest. which used to update the paritial portions.
Can I run backend method first, but still want to fire the JS function?
First two answers are already well answered. For third one you can try Jquery Ajax-
function SomeFunction(){
$.ajax({
type: 'POST',
url: "#Url.Content("Controller/ActionResult")",
data : {
*yourparameter:value* //data
},
dataType: 'json',
success:function(result)
{
//javascript stuff
}
});
}
ClickHereToSee
In traditional javascript AJAX, we know if readystate is:
0 - The request is not initialized
1- The request has been set up
2 - The request has been sent
3 - The request is in process
4 - The request is complete.
When it comes to jQuery AJAX, we have:
complete property where we code what should happen after completion
success property where we code what should happen if the ajax request succeeds and
error property where we code what should happen if ajax request fails.
All of the above properties lets us code to do something after completion of ajax request. Where can I specify some code to execute something during processing(when readyState is 3) in Jquery Ajax??
As my AJAX script takes too long time to execute, which means, I will not attain 'complete' stage quickly. This seems like nothing is happening to the user. I wanted to initiate another ajax script at processing stage which gets information from server meanwhile and shows the user what has been done so far. Is it possible at all in Javascript? I know there is no multi-threading in Javascript.
I think I made my self clear. But, Please let me know if anything is not making any sense.
I handle this by initiating the first long running request, returning to the user immediately and allowing the process to fork server side for the extended processing.
The initial return ajax call to the user sets them up to 'watch' that process via a flag against the object ( I store them against the object in the database, but you could for instance watch file sizes or other stuff )
Subsequent ajax calls occur in a loop, each one returning setTimeout for the next call, and report on changes to that flag so the progress of the long running process is then visible. Completion of the long running process prompts NOT sending another setTimeout() and showing the overall results.
If your process is not that intensive, a simple spinner would probably do the job and no work for your server process. I usually handle that having $.ajax flip the visibility of a 'spinner' icon that's preloaded on my pages in the same spot for all.
According to jQuery's Ajax documention, they do not expose the readystate change event:
No onreadystatechange mechanism is provided, however, since success,
error, complete and statusCode cover all conceivable requirements.
It would be possible to show a loading image after the initial Ajax request is kicked off (and before getting any "complete" or "success" events, and then start polling a different URL via ajax which will give you the status of the first request, assuming your server can show progress of the long process before it completes.