热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

hrefjs改变link_ASP.netCoreMVC项目给js文件添加版本号

需求:使用ASP.netCoreMvc开发公司内部web系统,给视图中js(css,image也可以)文件添加版本号避免缓存问题。解决方法:

需求:使用ASP.net Core Mvc开发公司内部web系统,给视图中js(css,image也可以)文件添加版本号避免缓存问题。

解决方法:利用Taghelper提供的标签(asp-append-version)可以实现

script>

效果:

1348738b4d97d87f743159630f50a5b7.png

备注:刷新页面js版本号不会变化,直到变动js内容变化,版本号才会变化。下文根据源码,了解asp-append-version是如何实现的。

if (AppendVersion == true)
{
EnsureFileVersionProvider();if (Href != null)
{
var index = output.Attributes.IndexOfName(HrefAttributeName);
var existingAttribute = output.Attributes[index];
output.Attributes[index] = new TagHelperAttribute(
existingAttribute.Name,
FileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, Href),
existingAttribute.ValueStyle);
}
}

private void EnsureFileVersionProvider()
{if (FileVersionProvider == null)
{
FileVersionProvider = ViewContext.HttpContext.RequestServices.GetRequiredService();
}
}

解析IFileVersionProvider的实现,然后调用AddFileVersionToPath方法添加版本号,AddFileVersionToPath源码如下:

public string AddFileVersionToPath(PathString requestPathBase, string path)
{if (path == null)
{
throw new ArgumentNullException(nameof(path));
}
var resolvedPath = path;
var queryStringOrFragmentStartIndex = path.IndexOfAny(QueryStringAndFragmentTokens);if (queryStringOrFragmentStartIndex != -1)
{
resolvedPath = path.Substring(0, queryStringOrFragmentStartIndex);
}if (Uri.TryCreate(resolvedPath, UriKind.Absolute, out var uri) && !uri.IsFile)
{// Don't append version if the path is absolute.
return path;
}if (Cache.TryGetValue(path, out string value))
{
return value;
}
var cacheEntryOptions = new MemoryCacheEntryOptions();
cacheEntryOptions.AddExpirationToken(FileProvider.Watch(resolvedPath));
var fileInfo = FileProvider.GetFileInfo(resolvedPath);if (!fileInfo.Exists &&
requestPathBase.HasValue &&
resolvedPath.StartsWith(requestPathBase.Value, StringComparison.OrdinalIgnoreCase))
{
var requestPathBaseRelativePath = resolvedPath.Substring(requestPathBase.Value.Length); cacheEntryOptions.AddExpirationToken(FileProvider.Watch(requestPathBaseRelativePath));
fileInfo = FileProvider.GetFileInfo(requestPathBaseRelativePath);
}if (fileInfo.Exists)
{ value = QueryHelpers.AddQueryString(path, VersionKey, GetHashForFile(fileInfo));
}else
{// if the file is not in the current server.
value = path;
}
cacheEntryOptions.SetSize(value.Length * sizeof(char)); value = Cache.Set(path, value, cacheEntryOptions);
return value;
}private static string GetHashForFile(IFileInfo fileInfo)
{
using (var sha256 = CryptographyAlgorithms.CreateSHA256())
{
using (var readStream = fileInfo.CreateReadStream())
{
var hash = sha256.ComputeHash(readStream); return WebEncoders.Base64UrlEncode(hash);
}
}
}

通过AddFileVersionToPath源码可以弄明白:

  • js版本号 如何实现的?

在GetHashForFile方法,根据文件的内容利用SHA256算法得到其hash值,然后通过url编码得到js的版本号如:?v=b_XmH4_MtWTW4959ESAEqaO3-Tqh9QSlrJgwrQ1YplA

  • 为什么更改了js文件内容,版本号会改变?

第一次得到版本号,会放入缓存中( value = Cache.Set(path, value, cacheEntryOptions);),同时缓存添加过期条件,判断依据文件是否发生变化( cacheEntryOptions.AddExpirationToken(FileProvider.Watch(requestPathBaseRelativePath));),否-直接或从缓存中获取。是-调用GetHashForFile方法重新生成。

动手添加个获取版本号的扩展方法

public static class HttpContextExtends
{public static string AddFileVersionToPath(this HttpContext context, string path)
{return context
.RequestServices
.GetRequiredService()
.AddFileVersionToPath(context.Request.PathBase, path);
}
}

view中使用

@section pageScript
{

效果

da3319e49926b768c560ba1c9e6e143d.png




推荐阅读
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • andr ... [详细]
author-avatar
呀yuan-
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有