I know how a MVC application handles routing,
(/foo/bar get) request hits the server
route /foo/bar with get method is found or not found, if found route handles the request by calling a method which serves a view page with corresponding data filled up.
client gets a html document with many links to other pages.
Another link is another procedure just like this one.
However, I have been learning react+meteor pack, which is a SPA (single page application) without ssr(server-side rendering). The most critical part that gets me confused is routing.Let's say I have 3 different routes for my SPA. (/), (/route2), (/route3)
(/route2) request hits the server. What does the server serve ? The whole application code with (/route2) active or what ?
Let s say we are on (/) route and clicked (/route2) route. So what s happening now ? Does react empty the #mainDıv and put related component instead, from where, the bundle.js which already contains all of the views' html as components ?
Is there a way to send only requested page's html and js, and after showing the content, getting other pages' html and js in the background, without client even feels. So that when another route is hit, only data will be on the wire.
Finally , only sending the related page's html - css - js when requested,I don t don't know if such a technique exists, seems to lack the SPA experience, but I am not sure If it would lack SPA expereince. It would be great to explain how to approach this issue.
With a SPA you typically (read: virtually always) configure your server to serve the same bootstrap HTML/Javascript regardless of which URL has been requested. A request for /route2 will get the same HTML response as a request for / or any other URL (unless you have specific exceptions for specific reasons). The SPA always starts with the same bootstrap code and examines the current browser's URL, then dynamically loads content as needed. How exactly that content is loaded and when it is loaded depends on the specific framework/code/circumstances/configuration, but yes, ultimately the contents of the DOM are dynamically being replaced by Javascript.
Related
I'm writing a sever application in go providing a Rest-API. If the server gets a GET without JSON-content-type header it serves an empty html-page having a javascript module in its head. This javascript code uses fetch to consume the Rest-API and populates then according the document.body with content fetched from the server. Each "link" in the content triggers further calls to the API and corresponding updates to the content.
So far so good. But I made two irritating observations.
(obviously) the "back" and "forward" buttons of the browser stay inactive. Which seems logical since there are no loaded URLs associated with the content changes.
If I come to my Rest-UI from an other page and hit the browser's back-button I get as expected the other page back but if I hit now the browser's forward-button I see the JSON-response from my initial fetch instead of my Rest-UI content. Reloading my page makes it all good again but I can't offer that behavior to any user :)
Are there common approaches to deal with this behavior? E.g. removing the browser controls completely, feeding the browser-history "by hand" with js-callbacks, caching directives, ... (I'm inexperienced with js)
The root of the problem is that I overloaded the response of a GET request on the server-side: if the GET-request accepts JSON the server returns JSON otherwise it returns a html-page with the javascript which consumes the JSON. I. e. the javascript fetch for the JSON is the last GET-response for a given URL and goes as such into the browser's cache associated with that URL. A solution to that problem which works for me is to send a header with the JSON response turning of caching and signalling the browser with the "Vary"-header that the response depends on the "Accept"-header. An other solution might be to add distinct endpoints to the server for the Rest-requests.
everyone. I am making a website with t-shirts. I dynamically generate preview cards for products using a JSON file but I also need to generate content for an HTML file when clicking on the card. So, when I click on it, a new HTML page opens like product.html?product_id=id. I do not understand how to check for id or this part ?prodcut_id=id, and based on id it generates content for the page. Can anyone please link some guides or good solutions, I don't understand anything :(.
It sounds like you want the user's browser to ask the server to load a particular page based on the value of a variable called product_id.
The way a browser talks to a server is an HTTP Request, about which you can learn all the basics on javascipt.info and/or MDN.
The ?product_id=id is called the 'query' part of the URL, about which you can learn more on MDN and Wikipedia.
A request that gets a page with this kind of URL from the server is usually a GET request, which is simpler and requires less security than the more common and versatile POST request type.
You may notice some of the resources talking about AJAX requests (which are used to update part of the current page without reloading the whole thing), but you won't need to worry about this since you're just trying to have the browser navigate to a new page.
Your server needs to have some code to handle any such requests, basically saying:
"If anybody sends an HTTP GET request here, look at the value of the product_id variable and compare it to my available HTML files. If there's a match, send a response with the matching file, and if there's no match, send a page that says 'Error 404'."
That's the quick overview anyway. The resources will tell you much more about the details.
There are some solutions, how you can get the parameters from the url:
Get ID from URL with jQuery
It would also makes sense to understand what is a REST Api and how to build a own one, because i think you dont have a backend at the moment.
Here some refs:
https://www.conceptatech.com/blog/difference-front-end-back-end-development
https://www.tutorialspoint.com/nodejs/nodejs_restful_api.htm
I have 2 project in 1 visual studio solution - Front end(HTML, CSS and JS) and Web API.They are running on separated ports - the FE on 37056 and API on 6596.In the JS files im targeting the wep api controllers - for example http://localhost:6596/api/Contacts/GetContacts, and the rendering the response from the Wep API on the HTML page.So far so good..
Here is come the problem - in the HTML the URLs are presented http://localhost:37056/about.html, so if for example i want to point to some specific resource returned by the Web API this is not possible.If i type for example http://localhost:37056/api/Contacts/GetContacts there will be wrong request.
How i can to bypass this - i have a blog post in the Front end that are feed with data from WEB api + database.I want to give the user opportunity to http://localhost:37056/api/Blog/Page=1 at the moment this is only possible if he/she navigate to the page called Blog in the Front end and click on specific Post and the URL in the browser will Not change.It will be http://localhost:37056/api/Blog without page numbers and so on (JS is making the requests).
Thanks in advance!
You're concatenating FrontEnd URL (http://localhost:37056) with the BackEnd resource (api/Contacts/GetContacts).
There are two ways to solve this:
Return from BackEnd absolute URL (instead relative) pointing to backend resource. This should be feasible, since backend "knows" it's own URL.
Store in FrontEnd base URL from backend, and concatenate it to relative paths returned.
I suggest using first option, because in case some resources are moved to a new location (for example, external resources stored in third-party servers) you don't need to update front end at all.
Could you use absolute uri instead of relative Uri in html?
today a question was raised here and I don't have an evident answer.
Assume that we concatenate and minify all resource files (CSS and Javascript) and declare them in the "Master-Page".
On a multi-page app, if a CSS file changes it will be recharged on the next full page load.
On a single-page app, the user can keep working for days and never recharge the main page where the CSS files are declared. The user will never see the changes until a Ctrl-F5 is issued.
I'm sure someone already thought of this and have an experience to share :)
For me, using WebSockets is not an option. First because it's overkill and second because not all my clients support the technology. Same reason applies to all WebSockets fallbacks... I won't keep hitting my servers because of this.
So, any ideas anyone? :)
BTW, we're using AngularJS if that can help for a specific solution.
Thanks!
I've getting through this same problem. My solution which is opinionated and may not respond to your criterias:
When I package my front-app and my server-app, I share a configuration file containing the current version of the front-app.
Front side: 75% of my routes change implicitly call a Webservice (route change resolve). SO each time I call my server I include a custom HTTP header (or a GET/POST param) containing the client version of the front-app.
Server side : I compare the front-app version (the one in the browser of the user, loaded last time user refreshed/loaded the SPA) with the front-app version of the shared configuration file :
If version matches : I Do nothing.
If version don't match I send a custom HTTP status error code (418 for example)
Then front side: I added a response Interceptor that intercepts any 418 error code and do a force-refresh of the whole app
That's it. Basically the event that "check" if the front-app version is the latest is a route change (that calls a WS via ajax). But you could add some infinite $interval calling a dedicated WS each 5 minutes or so...
I can add some code if needed.
Hope this helps ;)
Assuming that you are using AngularJS' routing via $route service and provider, then you can use $routeChangeSuccess event to perform a server request if there are significant changes that needs to be changed; if there are any then you can do a window.location.reload() to refresh the page and get all the updated resources and htmls.
The following process can be changed depending on how you want to implement it:
1. Setup a config file in your server indicating the app's version. You may also choose to assign different versions for different files but since you have concatenated all your resource files then I guess you may limit your version options in your configuration.
2. Create a service that contains all the necessary information(versions of files from the server) and methods to perform a server request to your server to check against the current file versions stored in the service.
3. Use $routeChangeSuccess event to perform a server request using the service that you have created in step 2, if the request returned a valid confirmation that there were changes then do the force page reload via window.location.reload().
I decided to add my final thoughts as an answer here too:
We went for a reduced solution for now.
As we have a "proxy service" that is (again for now) the only one that interacts with this application, we added the application version on the http header of all responses. If we receive a newer version, a popup appears notifying the user and a full page refresh is issued...
This solution won't work for applications that don't have their own "private" service.
I have an web app. Basically its a single page application. The initial page is a flat html file called index.html, with a single script declaration pointing to require.js. From there I use backbonejs to handle the client side logic. The index.html is being served by nodejs.
My issue is that, any action within the page, for example, i click on a link, the backbone router is called. Which is the behavior I want being a single page application.
For example: www.testserver.com then i click on a link which shows a modal screen for registration www.testserver.com/register, via backbone router with push state on
The issue arrises when, instead of accessing a certain link within the app, i open the url straight in browser. For example I paste, www.testserver.com/register, in the browser. The request is then sent to my node router. I am assuming this is the correct behavior, since the page doesnt exist yet, meaning the backbone router doesnt exist as well.
I was wondering, on what the correct work around for this is. What am i supposed to do, when i access this link? How do i pass the correct behavior back to my backbone application.
Thank you very much.
The server should return always the index.html page. When you start the router in your Backbone than, the router handle the navigation and call the function you defined for the actual route.
Assuming you don't need to do any SEO type stuff such that each unique URL loads its own metadata, just always serve the same index.html as stated. However if you want to have different static head content based on the URL, you should do that within node based on the path (e.g. keep an array of metadata for each route that you slip into a slightly-more-dynamic initial view template, based on your existing flat index.html)