I need to send some data to a web page, ideally in json format and I wonder what method is considered best, and why. Overall what good or bad experiences and surprises you had with them.
<script>var myJson = <? echo json_encode($myVar);
?>;</script>
advantage: the json is directly in javascript, were it will be used.
inconvenient: <script> in the middle of html/dom is bad (js belong
to .js files).
<div data-myJson='<? echo json_encode($myVar); ?>'>
advantage: html5 data thing is easy to work with. inconvenient:
bunch of data in the dom, it doesn't look elegant note: in my
case, I can afford to ignore "old" browsers.
ajax everything.
advantage: the json doesn't even need to be sent in this case, as it
will be already available (no page change). inconvenient: not
really an option as I would need to rewrite the full website.
instead of sending the full json, store it in the session and send a
key.
advantage: less data moving around inconvenient: the
data/session couple needs to be kept track of, and I like my session to be kept clean and tidy. (even if user just close the page before the flow is
finished) (which won't close the session).
Cookies.
advantage: herr.. is reverse evil a good thing? inconvenient: like session variables, but out of the cage.
Store the json in the session, and ajax it when the page is loaded.
advantage: somewhat elegant conceptually. inconvenient: heavy, as the ajax instruction has
to be added to a js file, and the session has to be managed. (and
cleansed. if the page load doesn't finish, the json will stay until
I cleanse it or the session finishes). Plus the html header means more bandwidth, and the we have to wait for the success to use the object.
other?
edit: as there seems to be a bit of confusion, with option 3 "ajax everything" I was meaning one page load, and all content loaded by ajax, even if you go through menus, links to other pages, forms submit, and such. I consider a more traditional navigation, (pages sent by the server as new a pages), with a page doing an ajax request to retrieve some value (here, my json object) on the server, as point 4 "session", as the main data has to remain on the server after the page has been sent to be later fetched by the ajax request. I did add option 6 for this.
I unhesitatingly recommend #1. You want to use your data in javascript, right? #1 is the simplest way and most direct way to ensure that your data exists, as a plain-old javascript object, when the page loads. I transfer data from the server side to the browser side all the time this way and it works beautifully.
You could arguably create better separation between your data and your UI by loading your data in an ajax call, but this is an additional http request, which will slow your page load.
Been a few years since this was asked, but for anyone else who finds themselves here and curious, I've been doing a variation of option #1 for quite a while. Additionally, Nike Plus does this as well. When the page loads, Nike sets window.np = {}
I've never really found a convention I love, but I've tried:
window.data
window.app.data (inspired by Symfony, literally uses the attribute app)
window.[app_name].data (inspired by Nike Plus)
window.initData (inspired by Google+)
In my case, I overwrite these JS objects with Backbone models/collections when the main Backbone app loads.
Related
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
Pls can anybody give me the clue of how to pass data from one page(test1.html) to another page(test2.html) and then later pass the previous 2 pages(test1 and test2.html) to a new page called last.html using javascript not php cos it is a local app. tanx
There are several ways to do it, you could pass a query string from page to page (prob a bad idea unless we are talking small bits of data you dont mind people seeing)
You could use local/session storage depending on the browsers you are looking to support.
You could also use a database and have a ajax post/get from page to page (not a great idea)
If you have something like php in the back end you could use a php session.
You could also use a cookie (again not the best idea but a good fallback for local/session storage)
Or you could have a single page app and use something like angular to show/change your page(s)
Imagine a page that shows a newsfeed. As soon as a user request said page, we go to the database (or whatever) and get the newsfeed. After the page is already loaded, we also have new news items added dynamically (through ajax/json). This means we effectively have two mechanisms to build a newsfeed. One with our server side language for the initial page request, and one with Javascript for any new items.
This is hard to maintain (because when something changes, we have to change both the JS mechanism and the Server side mechanism).
What is a good solution for this? And why? I've come up with the following scenarios:
Giving javascript an intial set, somewhere in the html, and let it build the initial view when document is ready;
Letting javascript do an ajax request on document ready to get the initial data; or
Keep it as described above, having a JS version and a SS version.
I'm leaning towards the first scenario, And for that I have a followup question: How do you give JS the dataset? in a hidden div or something?
Doing one more AJAX request to get the data isn't really costly and lets you have one simple architecture. This is a big benefit.
But another benefit you seem to forget is that by serving always the same static resources, you let them be cached.
It seems to me there's no benefit in integrating data in your initial page, use only one scheme, AJAX, and do an initial request.
Use a separate news provider to be loaded from page providing data as-is. This will keep things simple and make it load very quickly to be available nearly as fast as any embedded but hidden data set.
I am curious to know how "modern" web-apps/sites do postbacks, meaning when they are sending back user-input to the site be processed.
Do modern sites still use the old fashion <form>-tags or do they use some sort of javascript/ajax implementation? or is there even a third option?
I tend to use both, where a full page refresh from a normal <form> submit works, but if JavaScript is enabled you hook up to the submit event and override it. This gives you fancy AJAX if possible, and graceful degradation if it's not.
Here's a quick example (jQuery for brevity):
<form type="POST" action="myPage.htm">
<input type="text" name="UserName" />
<button type="submit">Submit me!</button>
</form>
If the user has no JavaScript, no problem the form works. If they do (and most will) I can do this:
$(function() {
$("form").submit(function() {
$.ajax({
url: this.action,
type: this.type,
data: $(this).serialize(),
success: function(data) {
//do something with the result
}
});
});
});
This allows the graceful degradation, which can be very important (depends on your attitude/customer base I suppose). I try and not screw over users without JavaScript, or if a JavaScript error happens on my part, and you can see from above this can be done easily/generically enough to not be painful either.
If you're curious about content, on the server you can check for the X-Requested-With header from most libraries and if it's present, return just the <form> or some success message (since it was an AJAX request), if it's not present then assume a full page load, and send the whole thing.
It will vary depending on what exactly is being done, but most web-apps will do a combination of AJAX for short content (esp where live/interactive updates are helpful without requiring a page refresh) and "old-fashioned" forms for longer content wherein a full page load is not an issue.
Note that nothing about AJAX prevents its use for long content as well as short.
Also note that from the stand-point of the code driving the server app, there is not necessarily much difference at all between a request coming from a standard form or a request coming from an AJAX submission. You could easily structure a single script to properly respond to both types of request (though in some cases you can save bandwidth by sending a shorter "data-only" response to the AJAX version, since the client-side code can be responsible for parsing the data into meaningful content).
Basically, there are three models.
The traditional form model uses form postbacks for every action that requires going to the server, and may use javascript to perform client-side tasks that make the user's life easier without compromising security (e.g. pre-postback validation). The advantage of this is that such a web application, if written correctly, will work without needing any javascript at all, and it is easier to make it work on a wide range of devices (e.g. audio browsers).
The server-centric ajax model uses ajax calls to provide partial page refreshes; the page is built like in the traditional model, but instead of triggering a full page post-back, client-side script uses ajax calls to send clicks and other events, and retrieves information to replace a part of the document (usually in JSON or XHTML form). Because you don't post the entire page every time, the response is usually quicker. This model is useful if you want to use ajax where possible, but still want to be able to fall back to traditional postbacks if javascript isn't available.
Client-centric ajax takes a different path; the core idea is that you write your entire application in javascript, using ajax to exchange data, not markup. When you click a button, the application sends a request to the server, and receives data. The data is then used for further processing on the client. This is more flexible and usually faster than the other methods, but it requires good knowledge of javascript. Applications written in this style generally don't work at all when javascript is disabled on the client.
Most decent web applications try to put progressive enhancement. Meaning that a simple old fashioned button click results in a form post which can be handled by the server. This is for the scenario of people who use an old browser or turned off javascript for some reason.
The enhancement can be done by using hijaxing. Meaning that that same page can perform, with the help of some ajax, the form post to the server but not the entire page. This enables users with javascript enabled to have a better user experience.
old fashion -tags or do they use some sort of javascript/ajax implementation?
In order to have javascript to work on something you still need that somethingl old fashioned tags. Web applications can be structured down to 3 major parts:
Content: HTML
Layout: CSS
Behavior: javascript/ajax
Which of the following code is better in building a delete -action for removing a question?
1 My code
<a href='index.php?delete_post=777>delete</a>
2 Stack Overflow's code
<a id="delete_post_777>">delete</a>
I do not understand completely how Stack Overflow's delete -button works, since it points to no URL.
The id apparently can only be used by CSS and JavaScript.
Stack Overflow apparently uses JavaScript for the action.
How can you put start the delete -action based on the content of CSS -file by JavaScript?
How can you start a SQL delete -command by JavaScript? I know how you can do that by PHP, but not by JavaScript.
Your method is not safe as a user agent could inadvertently crawl the link and delete the post without user intervention. Googlebot might do that, for instance, or the user's browser might pre-fetch pages to speed up response time.
From RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1
9.1.1 Safe Methods
Implementors should be aware that the
software represents the user in their
interactions over the Internet, and
should be careful to allow the user to
be aware of any actions they might
take which may have an unexpected
significance to themselves or others.
In particular, the convention has been
established that the GET and HEAD
methods SHOULD NOT have the
significance of taking an action other
than retrieval. These methods ought to
be considered "safe". This allows user
agents to represent other methods,
such as POST, PUT and DELETE, in a
special way, so that the user is made
aware of the fact that a possibly
unsafe action is being requested.
Naturally, it is not possible to
ensure that the server does not
generate side-effects as a result of
performing a GET request; in fact,
some dynamic resources consider that a
feature. The important distinction
here is that the user did not request
the side-effects, so therefore cannot
be held accountable for them.
The right way to do this is to either submit a form via POST using a button, or use JavaScript to do the deletion. The JavaScript could submit a hidden form, causing the entire page to be reloaded, or it could use Ajax to do the deletion without reloading the page. Either way, the important point is to avoid having bare links in your page that might inadvertantly be triggered by an unaware user agent.
Bind a click event on the anchor which start with "delete_post_" and use that to start an Ajax request.
$("a[id^='delete_post_']").click(function(e){
e.preventDefault(); // to prevent the browser from following the link when clicked
var id = parseInt($(this).attr("id").replace("delete_post_", ""));
// this executes delete.php?questionID=5342, when id contains 5342
$.post("delete.php", { questionID: id },
function(data){
alert("Output of the delete.php page: " + data);
});
});
//UPDATE
With the above $.post(), JavaScript code calls a page like delete.php?id=3425 in the background. If delete.php contains any output it will be available to you in the data variable.
This is using jQuery. Read all about it at http://docs.jquery.com/How_jQuery_Works.
The url you are looking for is in the js code. Personally I would have an id that identifies each <a> tag with a specific post, comment... or whatever, and then have a class="delete_something" on each one, this then posts to the correct place using javascript.
Like so:
Delete
<script type="text/javascript">
jQuery('a.delete_post').live('click', function(){
jQuery.post('delete.php', {id: jQuery(this).attr('id')}, function(data){
//do something with the data returned
})
});
</script>
You're quite correct that absent an href="..." attribute, the link would not work without JavaScript.
Generally, what that JavaScript does is use AJAX to contact the server: that's Asynchronous JavaScript and XML. It contacts a server, just as you would by visiting a page directly, but does so in the background, without changing what page the browser is showing.
That server-side page can then do whatever processing you require. In either case, it's PHP doing the work, not JavaScript.
The primary difference when talking about efficiency is that in a traditional model, where you POST a form to a PHP page, after finishing the request you must render an entire page as the "result," complete with the <head>, and with all the visible page content.
However, when you're doing a background request with AJAX, the visitor never sees the result. In fact, it's usually not even a human-readable result. In this model, you only need to transfer the new information that JavaScript can use to change the page.
This is why AJAX is usually seen as being "more efficient" than the traditional model: less data needs to travel back and forth, and the browser (typically) needs to do less work in order to show the data as part of the page. In your "delete" example, the only communication is "delete=777" and then perhaps "success=true" (to simplify only slightly) — a tiny amount of information to communicate for such a big effect!
It all depends on how your application is built, what happens at Stack Overflow is that the delete link click is caught by JavaScript and an Ajax request is being made to delete the post.
You can use a JavaScript library to easily catch clicks on all elements that match your selector rule(s).
Then you can use Ajax to send a request to the PHP script to do the SQL work.
On a side note, ideally you would not use GET for deleting entries, but rather POST, but that's another story.