JavaScript重新加载页面

45

为了在不完全重新加载所有内容的情况下重新加载页面,我正在使用:

window.top.location=window.top.location;

然而,当存在锚文本时,由于某种原因这种方法不起作用。在这种情况下,它似乎什么都没做,但更可能是刷新了锚点。

是否有任何修复方案可以在重新加载页面(如上所述)的同时避免重新加载缓存的图像和脚本?


1
如果有锚点,则它会滚动页面以显示第一个ID与锚点匹配的元素。 - Mike Samuel
不必详细介绍HTTP/1.1缓存和缓存验证,可以简单地说,接受的答案仅在JavaScript级别上工作,通过指定“浏览器是否可以从缓存重新加载页面”。但是,location.reload(false)无法阻止所有中间服务器(可能位于客户端和源服务器之间)返回其缓存副本。将随请求提交的查询字符串的随机未使用参数作为其一部分,是重新加载特定资源而不破坏其他资源缓存的实际做法。 - Joseph Myers
可能是重复的问题:如何使用Javascript重新加载页面? - Sam
5个回答

75
尝试使用location.reload(false)
MDN所述,第二个参数是一个布尔值,指示是否绕过缓存。 false 保持使用缓存,正如您所需。

顺便提一下,window.top.location=window.top.location 仍然更快,但如果有任何锚标签,我会使用 location.reload(false) - Alasdair
3
理论上这是一个很好的回答,但它并没有解决许多互联网服务提供商存在的问题,这些ISP在浏览器和服务器之间缓存文档。这在HTTP/1.1 RFC 2616的约束条件下是合法行为,但会导致代码更新需要相当长的时间才能传播到受影响的ISP用户。唯一的解决方案是完全禁用缓存,并使用服务器过期头或使用不同的查询字符串,根据RFC 2616的规定,这将强制ISP从服务器检索新的副本。 - Joseph Myers
2
@Joseph:如果您尝试绕过缓存,这肯定是一个重要的细节,但问题是如何不绕过缓存。 - icktoofay
1
@icktoofay OP说他/她想重新加载该页面,但不是完全重新加载所有内容。这确实意味着要绕过主页的缓存,但不是页面中使用的资源。在浏览器端,您的答案完美地只重新加载页面而不是其他资源,但它无法绕过仍在缓存主页的ISP当浏览器尝试重新加载它时。但通过附加不同的查询字符串,HTTP规范强制ISP“使其缓存的副本无效”并将请求发送到所需的服务器的主页。 - Joseph Myers
@Joseph:明白了,你说得完全正确。我想我忽略了那一部分。 - icktoofay
@icktoofay 谢谢,我很感激。你的答案对于典型情况仍然很好。我只是想为那些可能仍然遇到重新加载时出现神秘问题的少数异常情况添加一条注释。 - Joseph Myers

6

icktoofay解释了这个解决方法,所以我只回答这个问题:

然而,在存在锚文本时,出于某种原因,这种方法不起作用。在这种情况下,它似乎没有任何作用,但更有可能是刷新了锚点。

HTML 5描述了Location接口,该接口涵盖对document.location的赋值。

当调用assign(url)方法时,UA必须将参数相对于入口脚本的基本URL进行解析,如果成功,则必须将浏览上下文导航到指定的url。

因此,导航操作只看到绝对URL,因此仅分配片段与分配与页面URL相同的绝对URL和片段没有区别。

导航

8个片段标识符:将URL解析器算法应用于新资源的绝对URL和正在导航的浏览上下文的活动文档的地址。如果忽略任何片段组件,结果解析的URL的所有组件都相同,并且将使用HTTP GET或等效方法获取新资源,并且新资源的解析URL具有不为null的片段组件(即使它是空的),则导航到该片段标识符并中止这些步骤。

最后,导航到片段标识符

当用户代理需要滚动到片段标识符时,必须使用CSSOM视图规范中定义的滚动元素到视图算法更改文档的滚动位置,并设置对齐到顶部标志,或执行某些其他操作,以便将文档的指定部分带给用户的注意力。


4

确保页面本身被重新加载,但其他缓存元素不被重新加载的最好方法是使用随机参数更改location.search查询字符串。

例如,

location.search='?'+Math.random();

缓存没有被绕过,因此页面的所有元素都将从缓存加载,但是主页面本身会强制重新加载,因为HTTP需要为每个唯一的查询字符串/ location.search值向服务器发出另一个请求。如果您的页面本身是一个使用查询字符串的应用程序(例如file.cgi?param=xyz&param2 = abc ...),则必须附加到查询字符串而不是完全替换它:
if (location.search.length > 1)
location.search+='&'+Math.random();
else
location.search='?'+Math.random();

2
这很完美地解决了我的问题,因为我想在不重新提交的情况下刷新页面。 - Dr. Aaron Dishno

0
我一直在尝试解决以下情况:我有一个复杂的页面,其中包含一个小购物车,客户可以保存带有产品列表的项目。现在,我想让客户打开一个新页面以下载报告,同时保持父页面完整,包括打开的手风琴等。
使用IE8并仍在运行XP的客户在打开报告窗口后可能会导致父页面混乱。编程语言为ASP.NET,使用VB代码。这个解决方案对我有效。
Dim proj As String = "<script language=javascript> location.assign('/Projects.aspx');
window.open('Report.aspx?project=" & projid.Text & "&rpt=bill');</script>"
Session.Add("AddCart", idx.ToString("N0"))
Response.Write(proj)

使用location.assign可以刷新父页面,而window.open会在新窗口中打开报告。

会话变量用于跟踪应该打开哪个手风琴行。这是在Page_Load中处理的。

    If Not Page.IsPostBack Then
        LoadProjects()
        If Session("AddCart") IsNot Nothing Then
            Dim idx As Integer = Session("AddCart")
            ProjAccordion.SelectedIndex = idx
            Session.Remove("AddCart")
        ElseIf Session("CopyProj") IsNot Nothing Then
            Dim idx As Integer = Session("CopyProj")
            ProjAccordion.SelectedIndex = idx
            Session.Remove("CopyProj")
        End If
    End If

-2

不,那样行不通。尝试访问http://www.example.com/#test。然后运行`location.href = location.href;。注意当#test`存在时,该代码将不会重新加载页面。 - icktoofay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接