I'm attempting to AJAX in an MVC View to an empty tag using the standard jQuery AJAX call:-
function AjaxLoadPanel(url, id) {
var a = 1;
$.ajax({
url: url,
cache: true,
type: "GET",
success: function (data) {
if (data == "PageNotFound") {
window.location = "page-not-found";
}
else {
$(id).html(data)
}
},
error: function (response) {
$(id).html("");
}
});
}
The MVC controller simply returns the View with an MVC form within, and a HTTP Post beyond that to accept form data. When I put the pages with the div tag and the DLL and views on the server however, there is significant lag before the div tag is populated with the view return from the AJAX call. When I say significant lag, I mean 30 to 60 seconds after the page has loaded. The AJAX call does eventually finish, but such a problem renders the page useless to the unsuspecting user.
Stuff I've checked:-
All scripts are local to the site, no calls to external JS files.
All CSS are local to the site, no external calls.
The view and DLL's are definitely in the correct place
There are no scripts in the head tag.
The view does eventually get AJAX'd into the correct panel.
The wait time comes from calling the view specifically. Navigating to the URL of the view results in a 30 - 60 second wait before the view is returned.
How can I speed up the retrieval of the view? I need it to be within 1 second of page load if at all possible? Also, on localhost this feature works at lightning speed, loading in around 0.2 / 0.3 seconds.
Could it be the server being slow?
Thanks!
Mike.
Check your browser's network panel how long does the AJAX request takes to load.
I am quite sure it is problem with the backend/server. Are you 100% sure that the server backend code is same as your localhost backend code? Also do you use any database to retrieve the data. Could be also database issue.
We found the issue eventually. A datbase connection string login was wrong and the 30 second wait was always 30 seconds because of the length to try and connect to the database for, before causing an exception. At 30 seconds those views that don't directly rely on a database connection are still retrieved, hence the 30 second wait every time.
Thanks for your help!
Mike.
Related
Suppose I am using a free API service with a limit of c calls per m minutes.
I am using a tiny bit of javascript linked by the main html of my very basic site which contains something like the following:
$(function () {
//stuff
function getSomething() {
return $.ajax({
type: 'GET',
url: targetURL,
data: dataObject,
});
}
getSomething().done(function (returnedStuff){
//process returnedStuff
});
//more stuff
});
I have two questions:
Will there be an api call each time the page is reloaded?
If the answer to above is YES, then how does one prevent/limit the user/some other event from overshooting the api limit by their repeated reloading of the page.
Thanks for the help.
tldr: Making some assumptions from your high level example:
Will there be an api call each time the page is reloaded? Yes
If the answer to above is YES, then how does one prevent/limit the
user/some other event from overshooting the api limit by their
repeated reloading of the page. Read below
Further explanation:
Depending on whether your example code hits your own server side code which then makes the API code...or whether you're calling the API directly from the client. If you call the function on reload (document ready or whatever), then it will execute on every reload. Else, obviously only when you call the method (like via button click).
Remember, client side code is visible to the client - thus if that's your architecture, then you're exposing your API to the client. I can then for example write my own javascript to loop and call your API repeatedly...
My assumption is that the data does not need to refresh on every reload. With that in mind, I suggest you do the following:
Suggested way to limit API calls:
Use an ajax call to your own server.
On the server side, persist the data via caching of your choice and build in your own logic to test whether data needs to be refreshed (first call, after timeout, etc).
This way you do not expose the API url and details to the client side, and you have control over the amount of calls made to the API.
For optimization purposes, you can also rather cache data client side...but keep the logic and API call server side.
Hope this helps!
ps. If you need an example, please just provide what platform you're coding in and I'll be more than willing to whip up a quick example for you!
pps. You can simply cache client side and makde the API call from there with some logic built in to test the cache - but obviously anyone can then still call your API.
I am a novice writing a website using jquery and jquery mobile. This loads a set of questions in the form of a JSON file, using jquery ajax, and then users work through questions. On first opening, the page successfully opens 2 JSON files using code that looks like this:
function loadJSON (keytoload) {
$.ajax({
url: keytoload,
dataType: "json",
async: false,
success: function (keyloaded) {
dataset=keyloaded;
},
error: function (request,error) {
alert('Error has occurred please try again!');
}
});
}
I find that async has to be set to false for this to work. If async is true, the page is displayed without the data from the JSON file.
After the user works through a series of steps, a new JSON file is loaded to replace the first and this usually works fine. However, reloading the page is erratic. It works fine in Firefox/Chrome on Windows, but throws an error if a page refresh is done when loading on Android Chrome. So I assume there is a problem in my code somewhere.
Is there a better way I could do this?
Your problem here is cause by the fact that you don't use ajax correctly. You don't know how long is going to take until the result comes back from the server.
A correct architecture here will be:
display an loading div before starting ajax.
On success add the questions in the page.
On next display the loading again.
On success render the new content.
Just setting an variable on success is wrong; on success you render the content based on the values from backend. Also using an ajax in a synchronous way is not recommended, since it can block the script.
I have a server function like this
function very_long_task($data) {}
This function is called using $.ajax() function clients-side.
The problem is that when my server-side function very_long_task() is executed the site is locked down. Meaning that if I tried to view another page of the website from a different tab or window, the website will not load until the very_long_task() function has completed.
Is there anyway to get around this either server-side or client-side?
UPDATED: 2015-11-3
The AJAX call is actually called many times because it is looping through all the elements in a list and performing an action on each of them. The very_long_task() function is then being called on each element.
For example, if there were a list of 20 elements then the very_long_task() function would be called 20 times. This does help a little bit in the overall responsiveness on that page but not on other pages.
UPDATED: 2015-11-3
Also this is built with WordPress so I can leverage some of their functions, but I have had no luck with wp_schedule_single_event since I need a return value.
https://codex.wordpress.org/Function_Reference/wp_schedule_single_event
UPDATED: 2015-11-3
Here is an updated view of my
function very_long_task($data) {
session_write_close();
// Very long task...
return $data;
}
You'll want to call session_write_close() as soon as possible.
This is because while one page has called session_start(), the session file will be locked until the page finishes execution, or until the session is closed.
If this is not done, any page calling session_start() will wait for the lock to be lifted.
UPDATE
I think I know what's going on:
your browser limits the number of simultaneous connections to a server, typically somewhere between 2 and 10.
If you're making 20 asynchronous AJAX calls, and you open the Developer Console (F12 / control-shift-I), you'll probably find that not all of them are executing simultaneously. This would certainly leave no room for additional connections.
Note, that the session_write_close() is still necessary, otherwise the ajax calls will execute serially.
SUGGESTION
So, it is best to only make one AJAX call.
If you want parallelism, you can fork child processes server-side.
You probably won't be able to use jQuery for this, because you'll want to send data from the server and flush()-ing it as it becomes available (HTTP streaming).
One solution I used in a WP importer plugin is not to use AJAX at all, but perform the long running operation, pushing out HTML and a <script> tag to update the UI.
I'm not entirely sure what you mean by "locked down" but below are some things to try:
Make sure that your AJAX is asynchronous
$.ajax({
url: '/start_very_long_task.php',
async: true
});
Make sure your PHP accommodates the expected behavior
// start_very_long_task.php
function start_very_long_task()
{
ini_set('ignore_user_abort','on');
ini_set('max_execution_time', 0)
session_write_close();
do_very_long_task();
}
function do_very_long_task()
{
// Very long task stuff
// This can recursively call itself without making
// making multiple calls to session_write_close(), etc...
}
start_very_long_task();
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.
I am trying to load the HTML content of a webpage outside of my domain, which I can do just fine using functionality provided by this jQuery plugin: http://www.ajax-cross-origin.com/. However, when I print out the HTML there are pieces missing, which I assume is because the ajax request gets the HTML before the page is fully loaded. When I say "pieces missing," I mean that some tags that should have innerHTML in fact have none. Here's my code:
$.ajax({
crossOrigin: true,
url: "http://siriusxm.com/bpm",
success: function(data) {
console.log(data);
},
timeout: 5000
});
The crossOrigin attribute is from the plugin I mentioned. I get the same behavior with and without the timeout (and strangely, it doesn't seem as though the timeout is doing anything at all--when I check the console, it logs data pretty much immediately).
Is there a way to wait until the page is fully loaded before getting the content? For what it's worth, this is all part of a chrome extension I'm developing, so if there's anything else code-wise you might need just ask.
Thanks!
So according to your comments, the information you're looking for is just the Now Playing artist and Song, which you won't be able to get by loading just the source of the main page.
To find the data you're looking for just open up your Chrome DevTools, go to the network tab, and Refresh to see all requests on the page.
It looks like this is the request you want, you just need to update the timestamp every minute:
http://www.siriusxm.com/metadata/pdt/en-us/json/channels/thebeat/timestamp/08-12-03:48:00
Just parse that json and grab what you need. Of course they can always change the location or format of the file, but for right now that's what it is.
If the console log is showing all of the data you're looking for then the ajax call should be fine.
Any code in the success callback will be ran after the ajax call, so just use JQuery in the success callback function to insert data into the html. All I see there now is the console.log(data) unless you've removed some code.
The timeout just gives the ajax call a set amount of time to complete before it "times out", in other words it tells it to stop waiting after the set amount of time.