是否可以阻止 window.history pushstate() 向服务器发送 URL 请求?

Is it possible to prevent window.history pushstate() from sending URL request to server?

我正在制作单页网页。

我已经设置了一个 node.js 服务器并且我已经做到了,所以它可以确定来自用户的请求是 URL 还是资源请求。

当用户第一次加入时,我会向他们发送 index.html 文件,然后请求 css、图像和 javascript。 (这些都是骨架文件...例如,带有链接但不是实际内容的网站主要布局文件) 在客户端 javascript 我有代码查看用户所在的 URL,然后向服务器发送请求以获取更多 html 或 css,所有目前还不错。

然而,当我使用 window.history.pushstate() 更新 URL 时(用户点击 <a> 标签,我已经阻止了默认)它向服务器发送一个请求告诉用户说他们已经更改了 URL,我不希望这样。这是因为客户端 javascript 应该发送资源请求以便它可以在不刷新的情况下更新页面。

在我的服务器上,我认为没有办法判断客户端是否已经有 index.html,所以当它收到 URL 请求时,它不知道是否不要发送 index.html 文件(这会导致页面刷新)。

我想知道是否有办法阻止 pushstate() 告诉服务器用户已更改 url(因为这不是必需的)或知道用户是否已经更改的方法index.html 文件。

我知道这应该考虑到用户在多个不同的选项卡上打开网页(并且应该为每个单独的选项卡发送 index.html)或手动更改 url 等情况。

如果服务器必须接收 URL 请求,我的想法是使用 remoteAddress 和 remotePort 属性并以某种方式存储它们,然后在用户发送请求时比较它们。 (假设新选项卡将使用不同的远程端口)。

抱歉,我无法包含任何代码,因为我目前正在 phone 键入此代码,所以我不会在早上忘记此 post。我没有将 express.js 与 node.js 一起使用,因为我想在使用抽象模块之前轻松了解底层发生的事情。除了在前端使用 javascript 和 jquery 之外,我没有使用任何其他框架。后端纯节点。

这不一定是代码请求,因为我很乐意自己编写代码,我只需要有关如何处理此问题的建议。

所以,事实证明,我从未真正调用过调用推送历史记录的函数。下面是我的客户端代码(工作正常),以防万一以后有人遇到这样的愚蠢问题。

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__();