javascript - history.pushState URL 与 jquery 加载的交互导致页面获取失败?
问题描述
我正在使用history.pushState来设置 URL,同时使用 jquery .load来实际加载页面内容。我是历史 API 的新手,但我知道这是在动态站点中获取后退按钮/等功能的正常方式。
问题是我设置的欺骗地址在获取页面时以某种方式pushState
被使用.load
,这意味着它.load
试图获取不存在的页面,因此失败。DocumentRoot
在/var/www/bar
服务器上。在此示例中,用户尝试在服务器上的单个 html 文件中的两个点之间导航,该文件位于服务器的dir1/dir2/p1.html
下方DocumentRoot
。
- 当用户点击链接 1 时,服务器应该返回
dir1/dir2/p1.html #Container1
,并且地址栏应该显示foo.com/a/b/c
- 当用户点击链接 2 时,服务器应该返回
dir1/dir2/p1.html #Container2
,并且地址栏应该显示foo.com/a/b/d
那么我该怎么做呢?这是我尝试使用相对 URL 的方法,但它失败了:
$("#mainContent").load("dir1/dir2/p1.html #container1"); // good: XHR fetch foo.com/bar/dir1/dir2/p1.html
history.pushState(null, null, "a/b/c"); // good: shows 'foo.com/a/b/c' as the URL
...
$("#mainContent").load("dir1/dir2/p1.html #container2"); // bad: XHR fetch foo.com/bar/a/b/dir1/dir2/p1.html
history.pushState(null, null, "a/b/d"); // bad: shows 'foo.com/a/b/a/b/d' as the URL
这就是我使用绝对 URL 时发生的情况:
$("#mainContent").load("/dir1/dir2/p1.html #container1"); // good: XHR fetch foo.com/bar/dir1/dir2/p1.html
history.pushState(null, null, "a/b/c"); // good: shows 'foo.com/a/b/c' as the URL
...
$("#mainContent").load("/dir1/dir2/p1.html #container2"); // bad: XHR fetch foo.com/a/b/dir1/dir2/p1.html
history.pushState(null, null, "a/b/d"); // good: shows 'foo.com/a/b/d' as the URL
请注意,绝对路径更糟糕,因为 XHR 提取甚至不再使用DocumentRoot
( bar
)。谢谢。
编辑 1
在 Chrome/Windows 和 Firefox/Linux 上测试的相关案例,结果相同;绝对案例仅在 Firefox/Linux 上测试。
编辑 2
我一直在尝试并找到两种方法来解决这个问题,但我真的不明白发生了什么,所以我不会发布这个作为答案:
- 将所有 URL 设置
history
为深一层,因此a/b/c
变为a-b-c
. 我在历史 API 上搜索的所有内容都只显示一级深度 URL,所以这可能很常见 - 将
base
标签添加到网站的<head>
(<base "href=http://example.com/" target="_blank">
解决方案
更改历史状态将更改文档的URL,因此baseURI
如果没有其他东西已经更改它,例如<base>
元素。
因此,所有未来的网络请求确实将来自这个新的基础 URI。
要解决此问题,您可以在更改历史状态后手动设置 baseURI,
console.log( document.baseURI ); // /js
history.pushState(null, null, '/foo');
console.log( document.baseURI ); // /foo
// manually set document's baseURI via <base>
const base = document.createElement('base');
base.href = 'bar';
document.head.append(base);
console.log( document.baseURI ); // /bar
作为面向 StackSnippet 的 null 起源 iframe 限制的用户的 jsfiddle
或者,您甚至可以只在您的文档中从第一个页面加载开始将此 <base> 元素附加一次。
推荐阅读
- coffeescript - CoffeeScript - 使用推导将对象转换为矩阵
- javascript - 加载新页面时保持套接字连接
- responsive-design - 在W单位的Srcset中,浏览器是否考虑全分辨率高像素密度显示?
- json - 用 Jolt 提取第一个元素数组
- python - 如何连接两个数据集“纬度/经度日志数据”和“六边形网格数据”SQL或python
- unity3d - 如何统一创建菜单为我的武器购买弹药
- c++ - “表达式不可赋值”
- c++ - C ++将对象向量写入文件
- html - 为什么我的图像没有按照我喜欢的方式对齐?
- autohotkey - 再次按下按键时功能不同