ASP.NET MVC,IE 11,$(文档).ready和后台导航缓存

时间:2013-10-18 00:44:10

标签: javascript jquery html asp.net-mvc internet-explorer-11

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中运行时,面板不会更新。单击版本链接后,您必须手动刷新页面以使面板更新。

这说明了我的问题。

2 个答案:

答案 0 :(得分:1)

好吧,如果你看了你的链接。一个简单的解决方案是定义一个什么都不做的onbeforepageunload事件。不是一个理想的解决方案,但似乎它会验证这是问题的原因,并在您找到其他内容之前解决方法。

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

答案 1 :(得分:0)

经过几个星期的讨论,我终于找到了解决方法(如果客户端是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的,因此我们应该应用针对该浏览器的修复程序。