I have the following problem: I want to change one variable on a page. The input comes from another page so:
I'm using Node.js, Express.js and Ejs for this task.
Server - storing the values
Index page - Control page with input fields and send button
Display page - Shows the variable
I'm sending the variable with fetch post to the server. On the server I change the variable with the request body value and when I reload the "Display page" manually I see the new value. The problem is: I need to change it without any manual refresh or other things, because that won't be possible.
There is the possibility with "location.reload()" to refresh it every X second. But that's not the way I want to use, I really just want to refresh it when the variable changes. Is there a function (from express.js for example) I can use for it?
edit: I should mention that this project would be just used in our network and its not open for other users. Like an in-house company dashboard kind of.
So a "quick and dirty" solution can work too, but I want to learn something and wanted to do it the right way though.
This is a very common scenario that has several solutions:
Polling - The display page runs ajax calls in a loop every N seconds asking the server for the lastest version of the variable. This is simple to implement, is very common, and perfectly acceptable. However, it is a little outdated, and there are more modern and efficient methods. I suggest you try this first, and move on to others only as needed.
WebSockets - WebSockets maintain a connection between the client and server. This allows the server to send messages to the client application if/when needed. These are a little more complex to setup than just plain ajax calls, but if you have a lot of messages getting sent back and forth they are much more efficient.
WebRTC - This is taking it to another level, and is certainly overkill for your use case. WebRTC allows direct messaging between clients. It is more complicated to configure than WebSockets and is primarily intended for streaming audio or video between clients. It can however send simple text messages as well. Technically, if you want to persist the message on the server, then this is not suitable at all, but it's worth a mention to give a complete picture of what's available.
The simplest solution that came to mind is to have the server return the updated post in the body, then use that to update the page.
You can also read about long/short polling and Websockets.
One possible solution would be to add page reload code after a successful post-operation with fetch.
fetch(url, {
method: 'post',
body: body
}).then(function(response) {
return response.json();
}).then((data) => {
// refresh page here
window.location.replace(url);
});
Proper solution (WebSockets):
Add WebSocket server as a part of your Node.JS app
Implement subscriptions for the WebSocket, implement function 'state changed'.
subscribe on a method 'state changed' from your client browser app.
call ws server from your express app to update the clients when your variable is changed
Outdated (Polling):
Add express endpoint route: 'variable-state' Call server from your
client every n ms and check whether variable state is changed.
Refresh the page if variable is changed.
Related
I am developing a query PHP enabled chat, currently am using ajax to pull data from the server and display it in the chatbox but this makes use of multiple ajax requests to the client computer which causes it to slow abit....
This is what I am doing using ajax and yii2
function getdata() {
$.get("controller/action").
done(function(){
//process json
$("#chatbox").html(data);
})
}
then am using
windows.setInterval(getdata(),1000);
Are there better ways to fetch this son data without using ajax and jquery
I have checked on This link buts its not very helpful
You can use socket.io or websockets api which is an alternate option to ajax, So, by using socket.io, jquery, php OR nodejs one can build one to one private chat without using ajax, following links will help you out how to build private chat.
socket.io
WebSockets
Private chat reference 1
Private chat reference 2
A better approach is using nodejs instead of php. You can check this link for a really nice implementation of chat which you can use.
While php chat has performance issues like you mentioned, nodejs doesn't because instead of polling the messages it pushes them to the client when there is something to push. And also you receive ready to use solution right out of the box (of course you have to modify it) which will save you development time.
But if you still want to go with the php way, then you have these options:
jquery + ajax (like you are doing it right now)
php sockets - here is an example of php chat using websockets https://www.sanwebe.com/2013/05/chat-using-websocket-php-socket. This approach has its pros and cons. One of the major cons is that is not supported by old browsers and may be the setup process is not that easy. But I'll prefer it over the ajax requests.
You mention getting data from the database, but one could argue that, for the purpose of a chat application, the database is incidental. Maybe you want to store the chat history and the database is a natural place to do so, but the primary functionality is to transmit messages. So you are using the database as some kind of message buffer.
Websockets seems the best option, as others have mentioned. If you want PHP server-side, in addition to the Kraken framework as mentioned in a comment to your question, you can take a look at the Ratchet library. They have a tutorial for a simple chat in their site: http://socketo.me/docs/hello-world
Basically, you need another server-side process (in addition to your webserver) to receive and broadcast the chat messages. Following that tutorial, in the onMessage method of the Chat class you can do the insert in the database if needed, preferably asynchronously.
Client-side, you will need to connect to the websocket using Javascript. Simple example:
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log('Message received: ' + e.data);
addMessageToChatbox(e.data);
};
$('#yourChatInput').keypress(function(e) {
if(e.which == 13) { // "enter" was pressed
conn.send($(this).val());
$(this).val('');
}
});
function addMessageToChatbox(message) {
//
}
You can do a trick, suppose data is not json it is javascript file declaring single variable now you have to add it to document such as
below is your data.php(javascript generated by php)
in php
echo 'var x = {"name":"Anshuman"}'
In javascript
var s = document.createElement( 'script' );
s.setAttribute( 'src', 'data.php');
s.onload=callback;
document.body.appendChild( s );
function callback(){
console.log(x);
}
There aren't any sensible ways. You have to bring the new data in somehow right?
The to ways to do that are by reloading the page or by Javascript / Ajax to avoid the reload.
You could make the update one sided so that when Person A writes to person B the request is performed on the submit of the new message. This would mean that no new messages are retrieved unless one is sent. (Not practical)
Another method would be to have a last message time noted somewhere on its own and you could repeatedly check for that.
Should that time change you could fetch new data then but that would not fix the amount of requests... only the amount of data being transferred.
I suggest you look at the size of the data from the json/php. Have you ran tests to see how long that is taking or how it is performing?
I could refer you to this post which is using NON jquery requests if you like.
I am working on a pure HTML website, all pages are HTML with no relation to any server side code.
Basically every request to the server is made using AJAX, I send data from forms, I process this data in Handlers, then I return a JSON string that will be processed back on the client side.
Let's say the page is loaded with parameters in the URL, something like question.html?id=1. Earlier, I used to read this query string on Page Load method, then read data from the database and so on...
Now, since its pure HTML pages, I'm trying to think of an approach that will allow me to do the same, I have an idea but its 99% a bad idea.
The idea is to read URL parameters using JS (after the page has loaded), and then make an AJAX request, and then fetch the data and show them on the page. I know that instead of having 1 request to the server (Web Forms), we are now having 2 Requests, the first request to get the page, and the second request is the AJAX request. And of course this has lots of delays, since the page will be loaded at the beginning without the actual data that I need inside it.
Is my goal impossible or there's a mature approach out there?
Is my goal impossible or there's a mature approach out there?
Lately there are a good handful of JavaScript frameworks designed around this very concept ("single page app") of having a page load up without any data pre-loaded in it, and accessing all of the data over AJAX. Some examples of such frameworks are AngularJS, Backbone.js, Ember.js, and Knockout. So no, this is not at all impossible. I recommend learning about these frameworks and others to find one that seems right for the site you are making.
The idea is to read URL parameters using JS (after the page has loaded), and then make an AJAX request, and then fetch the data and show them on the page.
This sounds like a fine idea.
Here is an example of how you can use JavaScript to extract the query parameters from the current page's URL.
I know that instead of having 1 request to the server (Web Forms), we are now having 2 Requests, the first request to get the page, and the second request is the AJAX request. And of course this has lots of delays, since the page will be loaded at the beginning without the actual data that I need inside it.
Here is why you should not worry about this:
A user's browser will generally cache the HTML file and associated JavaScript files, so the second time they visit your site, the browser will send requests to check whether the files have been modified. If not, the server will send back a short message simply saying that they have not been modified and the files will not need to be transmitted again.
The AJAX response will only contain the data that the page needs and none of the markup. So retrieving a page generated on the server would involve more data transfer than an approach that combines a cacheable .html file and an AJAX request.
So the total load time should be less even if you make two requests instead of one. If you are concerned that the user will see a page with no content while the AJAX data is loading, you can (a) have the page be completely blank while the data is loading (as long as it's not too slow, this should not be a problem), or (b) Throw up a splash screen to tell the user that the page is loading. Again, users should generally not have a problem with a small amount of load time at the beginning if the page is speedy after that.
I think you are overthinking it. I'd bet that the combined two calls that you are worried about are going to run in roughly the same amount of time as the single webforms page_load would if you coded otherwise - only difference now being that the initial page load is going to be really fast (because you are only loading a lightweight, html/css/images page with no slowdown for running any server code.
Common solution would be to then have a 'spinner' or some sort (an animated GIF) that gives the user an visual indication that the page isn't done loading while your ajax calls wait to complete.
Watch a typical page load done from almost any major website in any language, you are going to see many, many requests that make up a single page being loaded, wether it be pulling css/images from a CDN, js from a CDN, loading google analytics, advertisements from ad networks etc. Trying to get 100% of your page to load in a single call is not really a goal you should be worried about.
I don't think the 2-requests is a "bad idea" at all. In fact there is no other solution if you want to use only static HTML + AJAX (that is the moderm approach to web development since this allow to reuse AJAX request for other non-HTML clients like Android or iOS native apps). Also performance is very relative. If your client can cache the first static HTML it will be much faster compared to server-generated approach even if two requests are needed. Just use a network profiler to convince yourself.
What you can do if you don't want the user to notice any lag in the GUI is to use a generic script that shows a popup hiding/blocking all the full window (maybe with a "please wait") until the second request with the AJAX is received and a "data-received" (or similar) event is triggered in the AJAX callback.
EDIT:
I think that probably what you need is to convert your website into a webapp using a manifest to list "cacheable" static content. Then query your server only for dynamic (AJAX) data:
http://diveintohtml5.info/offline.html
(IE 10+ also support Webapp manifests)
Moderm browsers will read the manifest to know whether they need to reload static content or not. Using a webapp manifest will also allow to integrate your web site within the OS. For example, on Android it will be listed in the recent-task list (otherwise only your browser, not your app is shown) and the user can add a shorcut to the desktop.
So, you have static HTMLs and user server side code only in handlers? Why you can't have one ASP .Net page (generated on server side) to load initial data and all other data will be processed using AJAX requests?
if its possible to use any backed logic to determine what to load on server side, that will be easy to get the data.
say for example if you to load json a int he page cc.php by calling the page cc.php?json=a, you can determine from the PHP code to put a json into the page it self and use as object in your HTML page
if you are using query string to read and determine, what to load you have to make two calls.
The primary thing you appear to want is what is known as a router.
Since you seem to want to keep things fairly bare metal, the traditional answer would be Backbone.js. If you want even faster and leaner then the optimised Backbone fork ExoSkeleton might be just the ticket but it doesn't have the following that Backbone proper has. Certainly better than cooking your own thing.
There are some fine frameworks around, like Ember and Angular which have large user bases. I've been using Ember recently for a fairly complex application as it has a very sophisticated router, but based on my experiences I'm more aligned with the architecture available today in React/Flux (not just React but the architectural pattern of Flux).
React/Flux with one of the add-on router components will take you very far (Facebook/Instrgram) and in my view offers a superior architecture for web applications than traditional MVC; it is currently the fastest framework for updating the DOM and also allows isomorphic applications (run on both client and server). This represents the so called "holy grail" of web apps as it sends the initial rendered page from the server and avoids any delays due to framework loading, subsequent interactions then use ajax.
Above all, checkout some of the frameworks and find what works best for you. You may find some value comparing framework implementations over at TodoMVC but in my view the Todo app is far too simple and contrived to really show how the different frameworks shine.
My own evolution has been jQuery -> Backbone -> Backbone + Marionette -> Ember -> React/Flux so don't expect to get a good handle on what matters most to you until you have used a few frameworks in anger.
The main issue is from a UX / UI point of view.
Once you get your data from the server (in Ajax) after the page has been loaded - you'll get a "flickering" behavior, once the data is injected into the page.
You can solve this by presenting the page only after the data has arrived, OR use a pre-loader of some kind - to let the user know that the page is still getting its data, but then you'll have a performance issue as you already mentioned.
The ideal solution in this case is to get the "basic" data that the page needs (on the first request to the server), and manipulate it via the client - thus ease-in the "flickering" behavior.
It's the consideration between performance and "flickering" / pre-loading indication.
The most popular library for this SPA (Single Page Application) page - is angularJS
If I understand your inquiry correctly. You might want to look more about:
1) window.location.hash
Instead of using the "?", you can make use of the "#" to manipulate your page based on query string.
Reference: How to change the querystring on the same page without postback
2) hashchange event
This event fires whenever there's a changed in the fragment/hash("#") of the url. Also, you might want to track the hash to compare between the previous hash value and the current hash value.
e.g.
$(window).on('hashchange', function () {
//your manipulation for query string goes here...
prevHash = location.hash;
});
var prevHash = location.hash; //For tracking the previous hash.
Reference: On - window.location.hash - Change?
3) For client-side entry-point or similar to server-side PageLoad, you may make use of this,
e.g.
/* Appends a method - to be called after the page(from server) has been loaded. */
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function () {
if (oldonload) {
oldonload();
}
func();
}
}
}
function YourPage_PageLoad()
{
//your code goes here...
}
//Client entry-point
addLoadEvent(YourPage_PageLoad);
Since you're doing pure ajax, the benefit of this technique is you would be able to easily handle the previous/next button click events from the browser and present the proper data/page to the user.
I would prefer AngularJS. This will be a good technology and you can do pagination with one HTML. So i think this will be good framework for you as your using static content.
In AngularJS MVC concept is there please read the AngularJS Tutorial. So this framework will be worth for your new project. Happy coding
I created a tabulation system for beauty pageants that show judges score on a projector. I created a presentation page for that using Codeigniter.
The HTML from that presentation page is purely written in Javascript. The page refreshes each second to get real-time data sent by the judges.
The not-so-cool thing about this logic is that when the page writes a lot of data, the page blinks every second. So the refreshing of the page is noticeable and somewhat disturbing.
This is a snippet of the code I'm working on.
$(document).ready(function() {
getJudgesScore();
setInterval(function(){
if (getNumFinalists() == 0)
getJudgesScore();
else {
window.open ('presentationFinalists','_self',false)
}
},1000);
});
You can imagine how much data is being sent and received every time this code is executed.
To sum this up, what I want to accomplish is instead of the client asking for data every second, the server initiates the connection every time a new data is saved to the database. Thank you for taking your time reading my concern.
This might help you to take necessary data from mysql server and send to client page.
Timer jquery run for after perticular time of interval.
<script src="../JS/Timer/jquery.timer.js"></script>
var timer = $u.timer(function() {
getJudgesScore();
});
timer.set({time: 1000, autostart: true});
refer this link also
https://code.google.com/p/jquery-timer/source/browse/trunk/jquery.timer.js?r=12
What you are attempting is a tricky -- but not impossible -- proposition.
#Chelsea is right -- the server can't genuinely initiate a connection to the client -- but there are several technologies that can emulate that functionality, using client connections that are held open for future events.
Those that come to mind are EventSource, Web Sockets, and long polling... all of which have various advantages and disadvantages. There's not one "correct" answer, but Google (and Stack Overflow) are your friends.
Of course, by "server," above, I'm referring to the web server, not the database. The web server would need to notify the appropriate clients of data changes as it posts them to the database.
To get real-time notification of events from the MySQL server itself (delivered to the web server) is also possible, but requires access to and decoding of the replication event stream, which is a complicated proposition. The discovered events would then need to result in an action by the web server to notify the listening clients over the already-established connections using one of the mechanisms above.
You could also continue to poll the server from the browser, but use only exchange enough data via ajax to update what you need. If you included some kind of indicator in your refresh requests, such as a timestamp you received in the prior update, or some kind of monotonic global version ID such as the MySQL UUID_SHORT() function generates, you could send a very lightweight 204 No Content response to the client, indicating that the browser did not need to update anything.
I'm a consultant working on a web app that's basically a single page app. All it does is constantly retrieve new json data behind the scenes (like once a minute), and then display it on screen.
Our clients load this app, and leave it running 24/7, for weeks on end. If errors happen when retrieving new json data, the app ignores it and keeps running.
We're rolling out an update, and want the existing clients to either become invalidated, or reload themselves without any user interaction. This feature wasn't "built in" by anyone, and we're trying to do this after the fact.
Is there some way to make the existing clients reload without telling our end users to just reload the page?
The following conditions define the app a bit more:
The app uses jQuery 1.9.0
Runs exclusively in Chrome
Retrieves new json data frequently using jquery
Throws away any errors it finds in json responses and uses old data.
EDIT:
I've had it suggested that we could try the following:
send invalid data through the JSON responses to crash chrome (like 500 megs of data, for example)
send window.location.reload through the JSON response (which supposedly won't work due jquery protecting against this type of thing)
send "script" data in the JSON response and if it gets $.html(....) at some point, then it may run the script as well.
and am open to any suggestions on getting this to reload or kill chrome, so the client is forced to reload the page.
If you're using $.ajax to request your data, and not specifically setting your content type, then you may be able to do the following on the server:
set the content type header to "text/javascript"
respond with javascript, e.g. window.location = "http://www.yoursite.com"
jQuery may eval that, and simply run your javascript.
No it is not possible. As far as I can tell you do not execute code from the JSON response (which is a very good thing). Thus you have no way of altering your current client's behaviour. According to your own statement:
"Throws away any errors it finds in JSON responses and uses old data"
You will not be able to crash the user's browser by sending invalid JSON data as the errors will be suppressed.
You can build in automatic deployment in to future versions by sending an application version number and testing for changes or by using WebSockets (which the application seems better suited to anyway as you can ensure your clients only poll the server when the JSON has actually changed).
If I get it correctly, create a version referance page, and make the client check this page very couple seconds, when you update the file, client will reload itself with this script.
var buildNo = "1.2.0.1";//
var cV = setInterval(checkVersion,(5*1000))//Every 5 sec.
function checkVersion(){
$.ajax({
url:"checkVersion.php?v="+buildNo,
dataType:"JSON",
success:function(d){
if(d.version != buildNo){//if version is different
window.location.reload();
//chrome.runtime.reload(); //for chrome extensions
}
}
})
}
if you cant add extra page, you may just add extra variable to end of your JSON data.
Let's assume that I have created my REST service smoothly and I am returning json results.
I also implemented API key for my users to communicate for my service.
Then Company A started using my service and I gave them an API key.
Then they created an HttpHandler for bridge (I am not sure what is the term here) in order not to expose API key (I am also not sure it is the right way).
For example, lets assume that my service url is as follows :
www.myservice.com/service?apikey={key_comes_here}
Company A is using this service from client side like below :
www.companyA.com/services/service1.ashx
Then they start using it on the client side.
Company A protected the api key here. That's fine.
But there is another problem here. Somebody else can still grab www.companyA.com/services/service1.ashx url and starts using my service.
What is the way of preventing others from doing that?
For the record, I am using WCF Web API in order to create my REST services.
UPDATE :
Company A's HttpHandler (second link) only looks at the host header in order to see if it is coming from www.companyA.com or not. but in can be faked easily I guess.
UPDATE 2 :
Is there any known way of implementing a Token for the url. For example, lets say that www.companyA.com/services/service1.ashx will carry a querystring parameter representing a TOKEN in order for HttpHandler to check if the request is the right one.
But there are many things here to think about I guess.
You could always require the client to authenticate, using HTTP Basic Auth or some custom scheme. If your client requires the user to login, you can at least restrict the general public from obtaining the www.companyA.com/services/service1.ashx URL, since they will need to login to find out about it.
It gets harder if you are also trying to protect the URL from unintended use by people who legitimately have access to the official client. You could try changing the service password at regular intervals, and updating the client along with it. That way a refresh of the client in-browser would pull the new password, but anyone who built custom code would be out of date. Of course, a really determined user could just write code to rip the password from the client JS programmatically when it changes, but you would at least protect against casual infringers.
With regard to the URL token idea you mentioned in update 2, it could work something like this. Imagine every month, the www.companyA.com/services/service1.ashx URL requires a new token to work, e.g. www.companyA.com/services/service1.ashx?token=January. Once it's February, 'January' will stop working. The server will have to know to only accept current month, and client will have to know to send a token (determined at the time the client web page loads from the server in the browser)
(All pseudo-code since I don't know C# and which JS framework you will use)
Server-side code:
if (request.urlVars.token == Date.now.month) then
render "This is the real data: [2,5,3,5,3]"
else
render "401 Unauthorized"
Client code (dynamic version served by your service)
www.companyA.com/client/myajaxcode.js.asp
var dataUrl = 'www.companyA.com/services/service1.ashx?token=' + <%= Date.now.month %>
// below is JS code that does ajax call using dataUrl
...
So now we have service code that will only accept the current month as a token, and client code that when you refresh in the browser gets the latest token (set dynamically as current month). Since this scheme is really predictable and could be hacked, the remaining step is to salted hash the token so no one can guess what it is going to be .
if (request.urlVars.token == mySaltedHashMethod(Date.now.month)) then
and
var dataUrl = 'www.companyA.com/services/service1.ashx?token=' + <%= mySaltedHashMethod(Date.now.month) %>
Which would leave you with a URL like www.companyA.com/services/service1.ashx?token=gy4dc8dgf3f and would change tokens every month.
You would probably want to expire faster than every month as well, which you could do my using epoch hour instead of month.
I'd be interested to see if someone out there has solved this with some kind of encrypted client code!
What you're describing is generally referred to as a "proxy" -- companyA's public page is available to anyone, and behind the scenes, it makes the right calls to your system. It's not uncommon for applications to use proxies to get around security -- for example, the same-origin policy means that your javascript can't make Ajax calls to, say, Amazon -- but if you proxy it on your own system, you can get around this.
I can't really think of a technical way to prevent this; once they've pulled data from your service, they can use that data however they want. You have legal options, of course; you can make it a term of service that proxying isn't allowed, and pull their API key if they don't comply. But most likely, if you haven't already included that in the TOS, you'd have to wait for, say, a renewal of their subscription to your service.
Presumably if they're making server-side HTTP requests to your service, those requests are all coming from the same IP address, so you could block that address. You'd probably want to tell them first, and they could certainly get around that if they wanted to.
With the second link exposed by Company A I don't think you can do much. As I understand it, you can only check whether the incoming request comes from Company A or not.
But each request issued to www.companyA.com/.. can't be distinguished from original request from Company A. Everyone they let in uses their referrer as a disguise.