3

IE 11 有一个功能似乎破坏了我的代码,称为Back navigation caching

当然,我的代码在 Google Chrome 中运行良好。

我有一个 MVC 应用程序和一个简单的脚本来加载部分页面以填充 div。这是在我的 HomeController 类中。

$(document).ready(function () {
        // load the stats partial view
        $('#stats_div').load('/Home/Stats');
    });

当我的页面第一次加载时,或者每当我刷新页面时,我的代码都会被调用,并且我的 div 会正确地填充我的部分页面。

在我页面的另一部分,我有一些看起来像这样的链接:

<li><a href="/Home/SelectVersion?version=1.0">1.0</a></li>

除了重定向到我的 HomeController 的 Index 操作之外,这些链接现在没有做任何事情,如下所示:

public ActionResult SelectVersion(string version)
{
    // do some stuff

    return RedirectToAction("Index");
}

每当单击这些链接时,浏览器都会重新加载页面。但是在 IE11 中,我的 $(document).ready 脚本没有被调用。

同样,这在 Chrome 中运行良好。

我所追求的是,​​当按下 SelectVersion 链接之一时,我需要重新加载统计信息部分页面。

我错过了一些明显的东西吗?我做错了吗?还是 IE11 只是在惹我。

正如上面的后退导航缓存链接中所建议的那样,我尝试了以下方法来尝试防止这种行为。

我添加了一个window.onbeforeunload没有效果的事件:

// does not help
window.onbeforeunload = function () {
}

我向这个函数添加了代码,并且每次都被调用。

我还尝试在 window.onpageshow 中加载数据,它的行为与 $(document).ready 相同:

// behaves the same as $(document).ready
window.onpageshow = function (e) {
    // load the stats partial view
    $('#stats_div').load('/Home/Stats');
}

换句话说,我无法让它发挥作用。还有其他人吗?

示例代码

以下是使用 Visual Studio 2013、Windows 8.1 和 IE 11 重现此问题的方法。

创建一个新的 MVC 应用程序,所有的默认值,没什么特别的。

将 Index.cshtml 的内容替换为:

<div class="row">
    <div class="col-md-6">
        <ul>
            <li><a href="@Url.Action("SelectVersion", new { version = "All" })">All Versions</a></li>
            <li><a href="@Url.Action("SelectVersion", new { version = "1.0" })">1.0</a></li>
            <li><a href="@Url.Action("SelectVersion", new { version = "2.0" })">2.0</a></li>
            <li><a href="@Url.Action("SelectVersion", new { version = "3.0" })">3.0</a></li>
        </ul>
    </div>
    <div class="col-md-6" id="stats_div">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">Overview</h3>
            </div>
            <div class="panel-body">
                <div class="col-md-12">
                    Choose a Version...
                </div>
            </div>
        </div>
    </div>
</div>

@section scripts
{
    <!--Load the AJAX API-->
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>

    <!--Script to render the charts-->
    <script type="text/javascript">

        // this function is called when the page is loaded and it is safe to access elements with jQuery
        $(document).ready(function () {
            // load the stats partial view
            $('#stats_div').load('/Home/Stats');
        });

    </script>
}

修改 HomeController.cs 以具有这些方法:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public PartialViewResult Stats()
    {
        ViewBag.VersionName = Session["VersionName"] ?? "Click on a Version";
        return PartialView("_Stats");
    }

    public ActionResult SelectVersion(string version)
    {
        Session["VersionName"] = version;
        return RedirectToAction("Index");
    }
}

在 Views/Home 文件夹中添加一个名为 _Stats.cshtml 的文件,其中包含以下内容:

<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title">Overview</h3>
    </div>
    <div class="panel-body">
        <div class="row">
            <div class="col-md-6">
                Version
            </div>
            <div class="col-md-6">
                @ViewBag.VersionName
            </div>
        </div>
    </div>
</div>

当您在 Chrome 中运行此程序时,每次单击其中一个版本链接时,右侧的面板都会更新。

当您在 IE 11 中运行它时,面板不会更新。单击版本链接后,您必须手动刷新页面以更新面板。

这说明了我的问题。

4

2 回答 2

1

好吧,如果你阅读你的链接。一个简单的解决方案是定义一个什么都不做的 onbeforepageunload 事件。不是一个理想的解决方案,但似乎它会验证这是问题的原因,以及一种解决方法,直到你能找到其他东西。

或者,您也可以定义一个 pageshow 事件,并在其中调用 load 。

于 2013-10-18T02:44:20.850 回答
1

坐了几周后,我终于找到了一种解决方法(如果客户端是 IE11,则受到重定向到其他页面的启发)。

if (window.navigator.msPointerEnabled) {
    window.onload = function () {
        if (!window.location.hash) {
            window.location = window.location + '#ie-workaround';
            window.location.reload();
        } else {
            history.replaceState({}, document.title, window.location.href.split('#')[0]);                        
        }
    }

}

不是最好的解决方案,但由于这高度特定于 IE11,因此我们应该应用特定于该浏览器的修复程序。

于 2019-02-07T00:42:04.543 回答