How does one limit rate of api calls despite page reload? - javascript

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.

Related

Is it Possible to Perform a background PHP server task from an AJAX call that will not lockup your site?

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();

How do you make a link perform an action without reloading a page?

The clearest example of this I could think of is the Reddit Upvote/downvote buttons how when you click the button, the value for upvotes is updated, the upvote button lights up, and the page DOES NOT reload, you just stay exactly where you are on the page.
I am trying to make a feature similar to this and I can totally figure out how to do it with reloading, but I want it to not reload so the user experience isn't disrupted.
Is it possible to do this with php? or would I need to use javascript or something?
The action I would need it to perform would be a basic update query in the database.
This would be done with an Ajax call to your php script. Ajax is designed for these asynchronous updates and/or reloads.
Another way you can do this is with HTML5 WebSockets. You could have the client send a trigger to the server when the user clicks the upvote, and then the server could update and push back the data. It would, however, be a bit overfill for this.
If what you want to do is to contact a server to either send it some state or to retrieve some state from the server (or both), then you would use AJAX with javascript in order to contact the server without reloading the page. You can then also use javascript to update the state of your page after the operation. That is generally what the Reddit page you refer to is doing.
Conceptually, you'd set up your page like this:
Put the link on the page.
With javascript install an event handler so you are notified of a click on the link.
When the link is clicked, your event handler will be called.
Prevent the default behavior of the link so the browser doesn't navigate to a new page.
Then, in the event handler, send your data to the server using AJAX. You will obviously need a URL on your server and server process that can accept and process the data for you and return a value if you need to.
If you need the response from the server, then set up a callback function for when the AJAX call completes (this will be some indeterminate time in the future).
Then, if you need to change the current page in any way (like show one more upvote), then you can modify the current page with javascript to show that new state.
Ajax is easier to use with a library (like jQuery) that contains some ajax support code, but you can certainly implement it in plain javascript too.
Here's one example of ajax with plain javscript. You can find many other examples with Google.
This MDN tutorial on AJAX seems pretty helpful too to show you how it works.
You could use JavaScript to do this. Here's a quick sample:
Vote Up
Simple solution in JavaScript:
var el = document.getElementById("upvoteBtn");
el.addEventListener("click", onVoteClick);
function onVoteClick(e) {
e.preventDefault();
// do something
}
Here's a fiddle.
NOTE: I see you'd be updating the database. In that case, you would have to use AJAX in the onVoteClick function (or use XMLHttpRequest) for this. JavaScript is a client-side programming language and will not be able to communicate to the server without the use of AJAX or XMLHttpRequest. Using the jQuery library, you should be able to write AJAX pretty easy.
It's called AJAX.
With AJAX you can send a request in the background.
The easiest way is to use the jquery libary for this.
You can also output some data as JSON back to the script if you want to take some other actions depending on the result from that query.
A good tutorial is this one.
It also explains how this requests (called: XMLHttpRequest) work.
You need to use Javascript's XMLHttpRequest
You can use AJAX...
It allows you to use JavaScript (client side) to call server side functions. Here's a good example.

How should I handle many AJAX calls?

I am trying to write a plugin which will work a lot with my server. Every page load will invoke an AJAX call to my server for data, the server should return a simple string.
Now I am trying to understand what would be the best aproach for this type of program.
Should I just create an AJAX call every time I need the data or is there some method I could create an open connection (despite the change of webpages) to save on server power?
Should I somehow listen to some port or something of the sort?
Do I have other options or what should I do to do this the most efficient way?
You can use HTML5 websockets (http://www.html5rocks.com/en/tutorials/websockets/basics/)
If you use this approach, then you will need to re-think the way you program your webserver, since websockets don't follow the request-response paradigm AJAX do. Instead they use a connection to stream data so you will need to open a port on your server and listen to it, the way to do it depends on the language or framework you are using. This is fast and responsive but will only work on most modern browsers.
Other approach is using Long Polling (http://techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery). This is used by some chat clients. It works sending an AJAX request to the server, the server receives it and keeps it waiting until the data is available and then the response is sent. Then the client makes another request, waits and repeats.
Probably you will almost never want to send simple strings to the client. It's almost always better to use XML or JSON to encode the response.
Just create a simple AJAX call and put it on each page, or save it as it's own file and put a server include on each page in the header. Simple as that!
$(document).load(function(){
$.ajax({
type: "POST",
url: "/where_your_string_is.php",
success: function(msg){
$("#stringHolder").html(msg);
}
});
});
Websockets API allows bi-directional communication, but I've just found that there's another option called HTML SSE that might be used if you only need to pull data. So if you've stumbled upon this question, consider this option as well.

How to make auto-updating (ajax) counter correctly? Or how to disable network log?

I'm trying to make auto-reload counter (for ex.: Messages [num]).
So, I just in setTimeout(); getting JSON code from test_ajax.php. I think it's not correctly..
Can I send info by server (I think not, but suddenly I something don't know..)?
Why I think that's not correctly: because when I'm looking in my chrome network log (F12 -> network tab), I see a lot of requests (to test_ajax.php), but when, I'm visiting vk.com (great example for ajax) or facebook.com, I don't see any requests while something will not change.
So, what's incorrectly in my solution (or what's bad..)?
UPD: Sorry, vk.com sending requests to q%NUM%.queue.vk.com every 25s, but until 25s last request's status is "Pending". When someone, for example, sending me a message it immediately display it. And request has parameter "wait" which equals 25. This delay in requests doing on server side.. But how?
Ajax counter can be done in easy just include below files
index.html
counter.php (ajax file)
necessary images
JS file (for jquery paging call)
download link: https://docs.google.com/open?id=0B5dn0M5-kgfDcE0tOVBPMkg2bHc
What you are looking for is called COMET (also sometimes called Reverse AJAX) techniques.
Doing what you want to do, e.g. regular polls, is one way of doing it.
A lot is actually happening on the server side; to avoid recreating new connections on every poll, some servlet containers like Jetty started to implement techniques like Continuation which basically maintain a two-way connection open.
In the Java world, with Servlet 3, you have asynchronous calls as part of the specs.

On click, redirecting to another URL if server slow?

Is it possible (in Javascript, ajax, other e.g. on the client site) to redirect the user to another URL if first URL slow to answer (when he clicks on a link) ?
A href=URL1 but if no answer from server1 after 1 second, redirection to URL2 (another server)
I was thinking about something like on event onclick :
redirection to URL1, timer, redirection to URL2 but if server 1 is not responding, the code after won't be executed...
Or then using AJAX, but I don't see how
The case ; a click on a page (a href=urltracking), urltracking redirect to URL2, but urltracking server can be slow...
I'm afraid it's not possible in this way. You can measure the response time by "timeout check" with a dummy AJAX call, if the target URL lays in your domain. Something like "send test GET, if server doesn't respond in XX secs then rewrite URLs to backup sites". But it's not suitable for general use.
Are both these sites your own? Maybe you should buy a load balancer. This is essentially a server that monitors performance of two webservers and redirects requests to the one that is least busy.
I always try to avoid situations where a 3rd party site can slow down my own site.
Perhaps you can make the call in some asynchronous form instead? Have a piece of javascript fire within the DOM ready event that makes the call to the tracking server instead, something like (in jQuery):
$(function(){
var tracker = new Image();
tracker.src = "http://tracker.com/path/to/tracker
});
other methods that can work are just a plain old tag, or an , etc. The key being that this loads after your page, and not before it. The tracking server will never know the difference.
Pay more money for a better server(s) and in extreme case with a load balancer. You should never need to do something like this client side.
You can use setTimeout Function of javascript.
setTimeout("function()",1000);
here in function you need to write code for redirection.
Also see this question for complete reference.
Correct me if I am wrong.

Categories