玩转C科技.NET

从学会做人开始认识这个世界!http://volnet.github.io

导航

统计

巧用Link标签加载资源,确保加载完为止

上一篇,我们讲到 如何直接强制客户端刷新.js文件 ,文章利用了缓存机制的若干特点。

这一篇,将利用一个大家常见的标签,来加载一些大家认为需要加载的资源。

初衷

我们都知道link标签是用来加载css文件的,不知道有多少童鞋误以为它只能加载css文件呢?又有多少童鞋把它忘记了呢?我们为什么要花单独一篇文章来写link,也正是要提示自己时刻不要忘记浏览器对待事物的方法。

假设你是一个浏览器的开发商,你在做link标签的时候,需要加载css文件,这是你的初衷,但是在你的页面开始加载之前,你其实并不知道你所加载的css文件,到底是不是真正的css文件,它可能不存在,它可能是个别的东西,它也可能真的如你所愿是css,但是这一切的判断,都在最后才能知道。

我们经常会遇到需要在当前页面跳转之前,加载一些数据,可能是为了缓存,也可能是其他原因,比如获取Http Headers等。

这里举个例子,我们知道清除Cookies的时候,我们需要从当前域下发送set-cookies http header,这个时候,当我们遇到需要同时清理多个域Cookies的时候(跨域还需要设置Http Headers P3P,理解P3P可以参考http://www.cnblogs.com/volnet/archive/2012/11/25/2787197.html 文章的解释。),我们就需要在一个页面同时请求多个域的清理Cookies的http headers,我们通常会有个页面用来发送这些请求,假设这里是一个跨域退出的操作,也就是向多个域获取各自清理Cookies的http headers,通常我们会在退出后跳转到一个页面(比如登录页面),那我们如何保证在跳转前,这些页面都已经被调用了呢?

这里就可以用到link标签了。也许你会问为什么不是多个ajax请求呢?面对跨域问题,ajax通常会有所限制,需要浏览器进行特殊设置,而link标签则没有这样的顾虑,它默认就支持跨域。

link标签的加载是阻塞的,也就是说在没有加载完之前,页面是不会继续跳转的。(当然这有时可能成为另一个问题,如被调用的页面永远也不终止返回,该页面就永远会卡死,这可以在加载link前通过脚本setTimeout来移除link)。

结论

link能够保证所加载的资源在页面跳转之前加载完成。

下面的示例佐证了这样的结论:

1、Block.aspx.cs 一个用来模拟超长加载时间的资源

2、MetaRefreshWithBlock.aspx 一个用来加载Block的跳转页面

3、Content.aspx 一个目标页面

Block.aspx.cs

    public partial class Block : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Clear();
            int seconds = 0;
            while (seconds < 10)
            {
                Response.Write(string.Format("Seconds = {0}<br />", seconds));
                Response.Flush();
                System.Threading.Thread.Sleep(1000);
                ++seconds;
            }
            Response.End();
        }
    }

MetaRefreshWithBlock.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MetaRefreshWithBlock.aspx.cs" Inherits="WebSiteLinkTagBlock.MetaRefreshWithBlock" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="refresh" content="3;url=Content.aspx" />
    <script type="text/javascript">
        function countTime() {
            var currentTime = 0;
            setInterval(function () {
                document.title = 'currentTime:' + currentTime;
                ++currentTime;
            }, 1000);
        }
        countTime();
        // 防止link 阻塞的超时间策略
        function timeoutLink() {
            setTimeout(function () {
                var link = document.getElementById('blockLink');
                if (link) {
                    link.removeNode();
                }
            }, 5000);
        }
        timeoutLink();
        function beforeLinkTag() {
            document.write('Before link tag.');
        }
        // 该方法早于meta http-equiv="refresh"执行
        beforeLinkTag();
    </script>
    <link id="blockLink" rel="Stylesheet" type="text/css" href="Block.aspx" />
    <script type="text/javascript">
        function afterLinkTag() {
            document.write('After link tag.');
        }
        // 该方法早于meta http-equiv="refresh"执行
        afterLinkTag();
    </script>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            This is MetaRefreshWithBlock.aspx Page.
        </div>
    </form>
    <script type="text/javascript">
        function afterLoad() {
            document.write('After load.');
        }
        afterLoad();
        function refeshPage() {
            setTimeout(function () {
                window.location.href = "Content.aspx";
            }, 3000);
        }
        refeshPage();
    </script>
</body>
</html>

源码下载:http://files.cnblogs.com/volnet/WebSiteLinkTagBlock.rar

posted on 2012-11-24 14:41 volnet(可以叫我大V) 阅读(...) 评论(...) 编辑 收藏

使用Live Messenger联系我
关闭