Precomputing Client-side Javascript Execution - javascript

Suppose you were to build a highly functional single-page client-side application that listens to URL changes in order to navigate around the application.
Suppose then, that when a user (or search engine bot) loads a page by its url, instead of delivering the static javascript file and hits the api as normal, we'd like to precompute everything server-side and delivery the DOM along with the js state.
I am wondering if there are existing tools or techniques for persisting such an execution of state to the client.
I know that I could execute the script in something like phantom JS and output the DOM elements, but then event handlers, controllers and the js memory state would not be attached properly. I could sniff our user agent and only send the precomputed content to bots, but I am afraid google would punish for this, and we also lose the speed benefits of having sent everything precomputed in the first place.

So you want to compile, server-side and send to the client the results of requesting a resource at a specific URL? What is your backend written in?
We have an API running on GAE in Java. Our app is a single-page app, and we use the HTML5 history object so we have to have "real responses" for actual URLs on the front-end.
To handle this we use JSP to pre-cache the data in the page as it's loaded from the server and sent to the client.
On the front end we use Backbone, so we modified Backbone.sync to look for a copy of the data it's looking for locally on the page and if it's not there, only then to request it from the server as an AJAX call.
So, yes, this is pretty much what every site did before you had ajax. The trick is writing your app so that the data can be local in the page (or in localStorage even) and if not only then to request the data. Then make sure your page is "built" on the server end (so we actually populate the data in the HTML elements on the server end so the page doesn't require JS on the client end).
If you go somewhere else the data is dynamic and the page doesn't reload.

Related

I have trouble entering URLs in the address bar when creating routes with vanila javascript

I am trying to create routes with vanilla javascript but every time I type a URL in the address bar I get an error saying, 'Cannot GET /about'. I am requesting a link to a tutorial or an answer to this kind of problem since it is my first time doing it with vanilla javascript and I have no clue.
Taking "Vanilla JavaScript" to mean "JavaScript, running in the browser, without the use of third-party libraries":
What you want is not (reasonably) possible.
When you type a URL into the address bar, the browser makes an HTTP request to that URL, and the HTTP server for the origin of the URL (i.e. the scheme + hostname + port) is responsible for delivering something (typically a webpage) back to the client.
You can't substitute client-side JavaScript for that initial request to the HTTP server.
There is an edge case. I think a progressive web app can use a service worker to intercept the request and generate a response internally. This is no good for handling the initial request though since the PWA wouldn't be installed at the time.
Generally, when you are writing a single page application you will need two parts for your URL handling.
The first part is the History API. This allows you to write JavaScript which tells the browser:
In response to the click the user just performed, I am going to update the DOM. If you were to visit this URL then you would get the same result as the changes I am making to the DOM, so go ahead and update the address bar to represent that.
It also lets you hook into the browser's back navigation so you can undo those changes if the user click's back.
The second part is where you make sure that the server really does deliver the same content for that other URL.
There are three strategies for achieving this:
Have the server return a more-or-less empty HTML document that checks the URL as it loads and then populates itself entirely with JavaScript. This is a poor approach which might as well just use hash bangs.
Generate all the HTML documents in advance. This is a strategy employed by Gatsby and Next.js. This is very efficient, but doesn't work for frequently updated content.
Generate the HTML documents on demand with server side code. Next.js can do this too.
You can do this when you write vanilla JavaScript (kinda), but it takes a lot of work since you need to write all the code to run on Node.js (where you might not count it as vanilla any more) to generate the HTML documents. I strongly recommend using a framework.

How to client-side routing url that ends with file extension

Say a user gives the title of a note as 'onboarding.md'.
And the url ends up like this localhost:4000/ecme/onboarding.md.
Now upon a refresh with that url, I want my client-side router to handle it - load a component, calls an api via fetch, then loads the result into the component.
But I get a blank page with an error Cannot GET /ecme/onboarding.md.
No such error if I programmatically navigate to the note.
You can't, at least not really.
If the user is refreshing the page then the browser is asking the server for that URL.
Your client-side router hasn't even been loaded.
When you use client-side routing with "real" URLs (as opposed to hash-routing where all the route data is kept in the fragment identifier) then you must have server-support too.
Good router support would use server-side rendering so the page would be delivered complete from the server instead of being generated client side. This is efficient (no need to serve a bootstrap page and then have the client do all the work and making additional HTTP requests for data), search engine friendly, and means that if JS fails for any reason then the page will still be accessible.
There are frameworks to support this for most common SPA frameworks (e.g. React has Next.js).
The quick and dirty approach if you want to around SSR is to just configure the server to serve up the bootstrap HTML document that runs the client-side code for every URL it is asked for (or at least those not associated with a file). This doesn't have the benefits listed above and also ends up giving clients (including search engines) an HTML document even whey they should get a 404 Not Found error.

loading a web page for a fake query string

I don't even know how to phrase the title of this question, but hopefully the following description will explain my issue.
I have a web application that is made up of a single, bare search page with a search field. The search is actually performed by the client browser and results are loaded via ajax. In other words, the server does nothing but serve up the bare search page at http://server/index.html
Once the query is performed, I use history.pushState() to change the URI in the browser address bar to something more sensible like http://server/index.html?q=searchterm&page=1&size=10. Pagination is performed by prev and next links that too are called via ajax along with the appropriately incremented or decremented page and size values. All is good.
But, I want my application to be a good web citizen, and be bookmark-able. In other words, if someone enters http://server/index.html?q=searchterm&page=1&size=10 directly in the browser address bar, I want to load the results correctly. Except, if I send that URI to the server, the serve will croak unless I implement some server-side processing. And, that is something I don't want to do as that will change the complexity of my application completely. Unless I can do that with plain, vanilla nginx (my web server). In other words, I don't want to implement any server side scripting other than what can be done with the web server itself, such as SSI.
So, how do I solve this problem?
hi the exact term for what you are trying to do is "Client side routing". It involves a combination of manipulating the browsers history using history.pushState() [which you are already doing] and server side config setting
.htaccess if you are using apache
config file if you are using nginx.
The server side settings will make your web server your base index.html for whatever request the browser makes(http://server/index.html?q=searchterm&page=1&size=10) once loaded in the client you have to get the query string in the window address bar and handle accordingly(make an ajax request).
This implementation has implications when search engines crawl your site using the URL but that is not within the scope of this question.
this SO question will give you a start
actually, I think this is a lot easier than I thought. When I send the browser to http://server/index.html?q=searchterm&page=1&size=10, it doesn't complain. It simply sends back http://server/index.html. Then it is just a matter for me to use js to extract the query string and do my ajax bit. This should work.

Can Javascript access an external or localhost database or nodejs?

I'm using a javascript scripting engine for a MUD i'm playing, they have a javascript client hosted on their server. I'm wanting to store some information in a database and access it from the client (or inject it somehow into the client) but I'm not seeing how I could do that.
Basically I can write javascript files into the trigger section of the website and they fire. It has Javascript and JQuery options. It does not have a database option on their end, which is why I'm trying to add it myself.
I know client side javascript has a lot of restrictions on it, so I'm not sure how far I could really go with this.
I think you might be able to do this, but it's going to be hacky.
If you're able to attach a script node to the dom, you can trigger GET requests with no origin restrictions wherever you want. You would do that to your own backend.
You would have to throw away all good practices and use GET requests with a lot of query params so send data to that (your) backend.
You would have to write the backend so that it does whatever you want with the data, e.g. store it in the db.
You would have to make sure you return valid js to the client, even if it's only to dismiss it.
Alternatively...
you could load an iframe to a site you control, and change the iframe src with the data, and then do with the data whatever you want (like sending it to some bakcend of yours properly) in your site (that's loaded in the iframe) by detecting changes in the url...

Is it possible to make server push without using javascript?

Is there some mechanism to provide server push technology using plain HTML, without using javascript (or any other script languages on the client side).
Under "server push" I mean process where the server to update some part of the page content when needed.
I don't know of any way that true server push can be used without any javascript in the page.
Without javascript, the only thing I'm aware of is a meta refresh tag that would tell the browser to refresh this page after some particular time interval. This tag applies to a whole page only. If you wanted only part of a page to be updated, you could use an iframe and have only the iframe be updated. Of course, this is not server push, but a client-driven auto-update and it will be run on a predetermined interval, not just when there is actually new data. For something smarter than this, you will need javascript.
The most efficient server-push would be to use javascript from the page to connect to your server over a websocket and then have the server just send data to the page via the websocket whenever it wants (true server-push). The client's javascript can then respond to the receipt of that websocket data by updating a particular piece of the page.

Categories

Resources