I'm making a single page webpage.
I've set up a node.js server and I've made it so it can determine whether or not a request from a user is a URL or a resource request.
When a user first joins I send them the index.html file which then requests css, images and javascript. (these are all skeleton files... e.g files that are the main layout of the website with links but not the actual content) On the client side javascript I have code that looks at the URL that the user is at, and then sends a request to the server for more html or css, all good so far.
However, when I update the URL using window.history.pushstate() (user clicks on <a> tag, I have prevented default) it sends a request to the server to tell the user that they have changed URL, which I don't want. This is because the client side javascript should send resource requests so it can update the page without refreshing.
On my server, I don't believe there is a way to tell if the client already has the index.html, so when it recieves a URL request it doesn't know whether or not to send the index.html file (which causes a page refresh).
I was wondering if there was a way to either stop pushstate() from telling the server the user has changed url (as it is nt necessary) or for a way to know if a user already has the index.html file.
I know this should account for cases such as the user having the webpage open on multiple different tabs (and index.html should be send for each individual tab) or the url is manually changed.
If the server has to recieve the URL request my idea was using the remoteAddress and remotePort properties and storing those somehow and then comparing them when a user sends a request. (assuming that a new tab would use a different remotePort).
Sorry I couldn't include any code as I'm currently on my phone typing this so I don't forget this post in the morning. I'm not using express.js with node.js as I want to get comfortable knowing what is going on underneath before I use an abstraction module. I'm not using any other framework except javascript and jquery on the front end. Pure node on backend.
This isn't necessarily a code request, as I am comfortable writing my own, I just need advice on how I should go about this.
So, as it turns out, I never actually called the function that calls push history. Below is my client side code (which works fine), just in case anyone runs into a silly issue like this in the future.
const main_page = ["/", "/index.html", "/home"];
const main_err = {
403: "FORBIDDEN",
404: "PAGE NOT FOUND"
};
const sub_err = {
403: "Your request has been denied by the server.",
404: "It looks like that page doesn't exist."
};
function get_error_message(status_num, html_request) {
if (!html_request) {return status_num};
return `<style>
.main-body {font-family: Arial}
.main-body h6 {font-size: 14px;font-weight: lighter;margin: 0 0 5px 0;}
.main-body h1 {font-size: 30px;margin: 0 0 12px 0;}
.main-body h4 {font-size: 18px;font-weight: lighter;margin: 0;}
</style>
<h6>${main_err[status_num]}<h4>
<h1>${status_num}</h1>
<h4>${sub_err[status_num]}</h3>`;
};
function make_request(url, html_request, callback) {
let req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState === 4) {
if (req.status === 200) {callback(req.responseText, true)}
else {callback(get_error_message(req.status, html_request), false)}}
}
req.open("GET", url);req.send();
}
function update_body(html) {document.getElementsByClassName("main-body")[0].innerHTML = html};
function nav_buttons(new_button) {
window.scrollTo(0, 0);
$(".main-link .active, .category-link .active").attr("class", "inactive");
$(new_button).attr("class", "active");
}
window.addEventListener('popstate', function(event) {
let data_passed = event.state
make_request(data_passed[0], true, update_body)
nav_buttons(data_passed[1])
window.scrollTo(0, 0)
});
function navBarButtonClicked() {
$(".main-link, .category-link").click(function(event) {
event.preventDefault()
let href = $(this).attr("href");
href = ((!main_page.includes(href)) ? href : "/home").substring(1);
let html_page = "assets/static/pages/"+href+".html"
console.log("REQUESTED PAGE:" + html_page)
make_request(html_page, true, update_body)
let id_of_element = "#" + $("> div", this).attr("id")
history.pushState([html_page, id_of_element], null, `/${href}`);
document.title = href
nav_buttons(id_of_element)
});
};
function __main__() {
let href = window.location.pathname;
href = ((!main_page.includes(href)) ? href : "/home").substring(1);
document.title = href; //check if valid route in future
let page_location = `assets/static/pages/${href}.html`
history.replaceState([page_location, `#header-${href}`], "", `/${href}`);
nav_buttons(`#header-${href}`)
make_request(page_location, true, update_body)
navBarButtonClicked();
};
__main__();