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

本文深入探讨了link标签在加载跨域资源时的高效应用,通过实验证明了其在页面跳转前确保资源加载完成的能力,并提供了一个案例来说明其在跨域退出操作中的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇,我们讲到 如何直接强制客户端刷新.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

### 可能原因及解决方案 #### 原因一:HTTP响应头设置不正确 浏览器可能因为服务器返回的MIME类型错误而拒绝加载CSS文件。如果服务器配置不当,可能导致CSS文件被当作纯文本或其他类型的资源处理[^1]。 #### 解决方案: 确保Web服务器正确设置了`Content-Type`为`text/css`。如果是自定义服务器环境或者使用本地开发工具,请检查其配置文件中的静态资源部分是否有误。对于Nginx或Apache这样的常见Web服务器,可以通过修改配置文件来指定正确的MIME类型: ```nginx types { text/css css; } ``` --- #### 原因二:缓存机制干扰 有时旧版本的CSS文件会被浏览器缓存下来,即使更新了实际文件内容,用户端仍会继续使用过期的缓存副本[^2]。 #### 解决方案: 强制刷新浏览器缓存(Ctrl+F5),或者通过URL参数附加随机数的方式防止缓存命中。例如,在HTML中引入CSS时可采用如下方法: ```html <link rel="stylesheet" href="/styles.css?v=1.0"> ``` 每次更改CSS文件后调整查询字符串中的版本号即可规避此问题。 --- #### 原因三:跨域资源共享(CORS)限制 当CSS文件位于不同的域名下时,如果没有适当配置CORS策略,则目标站点不允许外部访问这些资源。 #### 解决方案: 在托管CSS文件的服务端开启相应的CORS支持。比如Node.js Express框架下的实现方式如下所示: ```javascript const express = require('express'); const app = express(); app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); // 静态文件服务中间件 app.use(express.static(__dirname + '/public')); app.listen(3000); ``` 上述代码片段允许任何来源请求该服务器上的资源,并开放必要的头部字段供客户端验证合法性。 --- #### 原因四:Django项目特定情况 针对基于Django框架构建的应用程序而言,若发现尽管已按照官方文档指引成全部步骤却依旧存在样式丢失现象的话,那么很可能是由于某些细节遗漏所致。 #### 解决方案: 重新审视项目的settings.py文件里关于STATIC_URL以及STATIC_ROOT变量设定是否准确无误;另外还需注意collectstatic命令执行后的部署流程是否存在偏差——即生产环境中所使用的webserver能否正常读取到由django-admin collectstatic收集起来的最终版静态资产目录结构及其内部各项子项位置关系等等因素均需逐一排查清楚才行。 --- ### 总结 综上所述,造成JavaScript能够成功加载而CSS未能生效的现象背后隐藏着多种可能性,具体表现为但不限于以上列举出来的几个方面。因此建议开发者依据实际情况逐步排除潜在隐患直至找到确切根源为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值