javascript - 是否可以阻止 window.history pushstate() 向服务器发送 URL 请求?
问题描述
我正在制作一个单页网页。
我已经设置了一个 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 属性并以某种方式存储它们,然后在用户发送请求时比较它们。(假设新选项卡将使用不同的远程端口)。
抱歉,我无法包含任何代码,因为我目前正在手机上输入这个,所以我不会在早上忘记这篇文章。我没有将 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__();
推荐阅读
- javascript - 如何使用 Chart.js 使图表的背景颜色为渐变
- ios - 删除 UIVIewController 中的顶部空间 UIScrollview
- bash - 重写 curl 以便允许变量内的引号
- php - 正则表达式:如何捕获每一行以创建列表
- css - 为什么 CSS 变量不支持 Safari 中的图像?
- java - 通过 Spring CLI 将依赖项添加到现有项目
- android - Android 应用程序以编程方式接收传入的 SMS 消息并回复回复
- css - 如何使用 SCSS 选择父级
- authorize.net - 批量交易处理 - 自动支付场景
- python - Python, Outlook 检索一个人的电子邮件和这个人的经理的电子邮件