브라우저가 asp.net 응용 프로그램에서 최신 js 및 css 파일을 가져 오도록 강제


104

일부 브라우저는 js 및 css 파일을 캐시하여 강제하지 않으면 새로 고치지 못합니다. 가장 쉬운 방법은 무엇입니까?

방금 작동하는 것처럼 보이는이 솔루션을 구현했습니다.

페이지에서 버전 변수 선언

  public string version { get; set; }

web.config 키에서 버전 번호 가져 오기

 version = ConfigurationManager.AppSettings["versionNumber"];

aspx 페이지에서 자바 스크립트와 스타일 시트를 이렇게 호출하십시오.

<script src="scripts/myjavascript.js?v=<%=version %>" type="text/javascript"></script>
<link href="styles/mystyle.css?v=<%=version %>" rel="stylesheet" type="text/css" />

따라서 web.config에서 버전을 1.0에서 1.1로 설정하면 브라우저가 최신 파일을 다운로드하여 사용자와 사용자의 불만을 덜어줍니다.

더 잘 작동하는 다른 솔루션이 있습니까? 아니면 웹 사이트에 예기치 않은 문제가 발생합니까?


흥미로운 질문은 최근에 같은 문제가 있었지만 개발 테스트 중에 만 문제였습니다. 출시 후 해당 파일을 변경할 계획이 없으므로 크게 신경 쓰지 않았습니다. 향후 참조를 위해 솔루션을 알고 싶습니다!
Brett Allen

내가 볼 수있는 유일한 문제는 web.config의 변경 사항이 백그라운드에서 응용 프로그램 다시 시작을 호출한다는 것입니다. msdn.microsoft.com/en-us/library/aa478432.aspx
monty

질문 해주셔서 감사합니다. 이것은 큰 문제를 해결하는 데 도움이되었습니다.
Reddy

답변:


76

마지막으로 수정 된 타임 스탬프를 스크립트에 대한 쿼리 매개 변수로 지정하여이 문제를 해결했습니다.

확장 방법을 사용하여이를 CSHTML 파일에서 사용했습니다. 참고 : 이 구현은 1 분 동안 타임 스탬프를 캐시하므로 디스크를 너무 많이 쓰지 않습니다.

확장 방법은 다음과 같습니다.

public static class JavascriptExtension {
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;

        if (context.Cache[filename] == null)
        {
            var physicalPath = context.Server.MapPath(filename);
            var version = $"?v={new System.IO.FileInfo(physicalPath).LastWriteTime.ToString("MMddHHmmss")}";
            context.Cache.Add(filename, version, null,
              DateTime.Now.AddMinutes(5), TimeSpan.Zero,
              CacheItemPriority.Normal, null);
            return version;
        }
        else
        {
            return context.Cache[filename] as string;
        }
    }
}

그리고 CSHTML 페이지에서 :

 @Html.IncludeVersionedJs("/MyJavascriptFile.js")

렌더링 된 HTML에서는 다음과 같이 나타납니다.

 <script type='text/javascript' src='/MyJavascriptFile.js?20111129120000'></script>

1
이것은 mvc에 적합합니다. 최신 mvc 5 프레임 워크가이 문제를 처리하는지 궁금합니다. 번들링이-{version} 와일드 카드와 함께 사용하는 접근 방식도이 문제를 해결하는 방법이지만 새 빌드마다 파일 이름을 변경해야합니다 ...
kiev

웹 양식 웹 사이트에서 MVC 예제의 기본 사항을 사용하고 있으며 훌륭하게 작동하므로 공유해 주셔서 감사합니다!
Bryan

리소스 파일에 대한 마지막 수정 날짜 / 시간 스탬프 표시에 대해 걱정할 이유가 있습니까? 사용중인 파일에 몇 년 전의 날짜 / 시간 스탬프가있는 경우 회사에서 사용자에게 공개하고 싶지 않은 정보가 될 수 있습니까?
Bryan

대부분의 응용 프로그램이 따르는 표준 방식입니다. 그러나 해당 타임 스탬프는 애플리케이션을 배포하거나 빌드 할 때만 변경되어야합니다. 그렇지 않으면 사용자가 페이지를 새로 고치거나 애플리케이션의 다른 페이지로 전환 할 때마다. 브라우저는 좋은하지 않은, 다시 모든 스타일 시트와 자바 스크립트를 다운로드합니다
Tarun

2
페이지 성능에 미치는 영향은 무엇입니까? 페이지로드가 얼마나 지연 될 수 있습니까?
Durgesh Sonawane

28

솔루션이 작동합니다. 사실 꽤 인기가 있습니다.

Stack Overflow도 비슷한 방법을 사용합니다.

<link rel="stylesheet" href="http://sstatic.net/so/all.css?v=6184"> 

v=6184SVN 개정 번호는 어디에 있습니까 ?


이것은 허용 된 답변에 설명 된 것보다 훨씬 더 부담스러운 접근 방식입니다. 페이지가 제공 될 때마다 파일의 SVN 버전을 확인하는 것은 특히 시간이 지남에 따라 사용자 수가 증가함에 따라 성능 오버 헤드입니다.
Neolisk

4
빌드 중에 개정 번호를 가져오고 파일 (예 : 부분 .cs 파일)에 쓰고 해당 파일을 프로젝트에 포함 할 수 있으므로 런타임에 svn에서 읽을 필요가 없습니다. 이 접근 방식을 msbuild와 함께 사용하여 svn의 AssemblyInfo.cs 파일에 개정 번호를 넣었습니다.
Ramazan Binarbasi

2
글로벌 버전 / 개정 번호를 사용하면 적어도 한 가지 단점이 있습니다. 웹 사이트 업데이트를 게시하면 변경된 파일뿐만 아니라 모든 .js 및 .css 파일에 대한 브라우저 캐시가 무효화됩니다. 이것은 대부분의 응용 프로그램에서 중요하지 않지만 완전성을 위해 언급합니다.
아담 Tegen

배포 또는 빌드 중에 자동으로 assemblyinfo.cs 파일의 버전을 업데이트하는 경우 해당 번호에 부 버전을 사용할 수 있습니다.
kristianp

28

에서 ASP.NET 코어 (MVC 6)이은을 통해 상자 밖으로 작동하는 asp-append-version태그 도우미 :

<script src="scripts/myjavascript.js" asp-append-version="true"></script>
<link href="styles/mystyle.css rel="stylesheet" asp-append-version="true" />

1
알려 주셔서 감사합니다! 전에는 몰랐어요!
Federico Navarrete

18

JS / CSS에 번들을 사용하는 경우 ASP.NET MVC가이를 처리합니다. 번들에 GUID 형식으로 버전 번호를 자동으로 추가하고 번들이 업데이트 될 때만이 GUID를 업데이트합니다 (일명 소스 파일에 변경 사항이 있음).

컨텐츠로드 시간을 크게 향상시킬 수 있으므로 JS / CSS 파일이 많은 경우에도 도움이됩니다.

여기를 보아라


MVC 응용 프로그램에서 번들을 사용하는 경우 여기에 게시 된 답변의 방법이 필요하지 않다는 의미입니까? 그렇다면 번들링이 제가 생각했던 것보다 훨씬 더 중요합니다. 이 문제에 대해 설명해 주시겠습니까? 감사.
Jack

1
네, 맞습니다. 스크립트가 번들에 포함되어있는 한 번들의 소스 파일에서 변경 사항이 감지되면 각 번들에 대한 버전 번호를 자동으로 생성합니다.
jonesy827

그리고 개발자로서 여전히 골칫거리임을 잊지 마십시오. ASP.NET 번들링은 디버깅 및 개발 중에 도움이되지 않습니다.
it3xl

12

이를 위해 asp.net에 내장 된 방법이 있습니다 : 번들링 . 그냥 사용하세요. 각 새 버전에는 고유 한 접미사 "? v = XXXXXXX"가 있습니다. 디버그 모드에서는 번들링이 꺼져 있으며 web.config에서 make 설정을 켜는 경우 :

<system.web>
    <compilation debug="false" />
</system.web>

또는 RegisterBundles (BundleCollection bundles) 메서드에 추가합니다.

BundleTable.EnableOptimizations = true;

예를 들면 :

BundleConfig.cs :

bundles.Add(new ScriptBundle("~/Scripts/myjavascript.js")
                .Include("~/Scripts/myjavascript.js"));

bundles.Add(new StyleBundle("~/Content/mystyle.css")
                .Include("~/Content/mystyle.css"));

_Layout.cshtml :

@Scripts.Render("~/Scripts/myjavascript.js")
@Styles.Render("~/Content/mystyle.css")

그러나 이것은 릴리스 또는 프로덕션 환경에서만 작동합니다. 디버그 모드가 켜져있을 때 개발은 어떻습니까? 번들로 여전히이 문제가 해결 되나요?
VAAA

네, bundlind는 개발자의 삶을 더 쉽게 만들어주지 않습니다. 각 스크립트 변경 후 Ctrl-F5를 눌러야합니다. 그리고 프레임이 있으면 훨씬 더 재미있을 것입니다.
it3xl

6

질문에서 op에 의해 제공된 대답보다 더 간단한 대답이 있습니다 (접근 방식은 동일 함).

web.config에서 키를 정의하십시오.

<add key="VersionNumber" value="06032014"/>

aspx 페이지에서 직접 appsettings를 호출합니다.

<link href="styles/navigation.css?v=<%=ConfigurationManager.AppSettings["VersionNumber"]%>" rel="stylesheet" type="text/css" />

이 같은 I,하지만이 솔루션은 ... 그래서 약간까지 투표를 왜 걱정입니다
SimplyInk

@SimplyInk 모르겠지만 20 개의 다른 답변이 있으므로 관련이있을 수 있습니다. 작동하고 마음에 든다면 자유롭게 찬성하십시오.
JackArbiter

4

Adam Tegan의 답변을 기반으로 웹 양식 응용 프로그램에서 사용하도록 수정되었습니다.

.cs 클래스 코드에서 :

public static class FileUtility
{
    public static string SetJsVersion(HttpContext context, string filename) {
        string version = GetJsFileVersion(context, filename);
        return filename + version;
    }

    private static string GetJsFileVersion(HttpContext context, string filename)
    {
        if (context.Cache[filename] == null)
        {
            string filePhysicalPath = context.Server.MapPath(filename);

            string version = "?v=" + GetFileLastModifiedDateTime(context, filePhysicalPath, "yyyyMMddhhmmss");

            return version;
        }
        else
        {
            return string.Empty;
        }
    }

    public static string GetFileLastModifiedDateTime(HttpContext context, string filePath, string dateFormat)
    {
        return new System.IO.FileInfo(filePath).LastWriteTime.ToString(dateFormat);
    }
}

aspx 마크 업에서 :

<script type="text/javascript" src='<%= FileUtility.SetJsVersion(Context,"/js/exampleJavaScriptFile.js") %>'></script>

렌더링 된 HTML에서는 다음과 같이 나타납니다.

<script type="text/javascript" src='/js/exampleJavaScriptFile.js?v=20150402021544'></script>

2
야! 예제는 작동하지만 캐시 참조를 제거하거나 캐시를 사용하도록 코드를 수정해야합니다. 캐시를 사용하는 이유를 혼동 할 수 있기 때문입니다. 캐시를 사용하려면 context.Cache [filename] == null의 경우 context.Cache.Add 메서드를 사용하여 캐시에 파일 버전을 추가해야합니다. 하세요 context.Cache은 [파일 이름] = null는, 당신은 캐시 된 값 (context.Cache [파일 이름]) 반환해야하는 경우
디에 Obreja

1
Flavia, 귀하의 설명이 합리적이라고 생각하며 더 간단하고 효율적인 구현이라고 생각합니다. 유용한 의견과 피드백을 게시 해 주셔서 감사합니다.
Bryan

4

흥미롭게도이 사이트는 비록 안전해야하지만 일부 프록시 설정과 관련하여 설명하는 접근 방식에 문제가 있습니다.

Meta Stack Overflow 토론을 확인하십시오 .

따라서 업데이트에 GET 매개 변수를 사용하지 않고 실제 파일 이름을 사용하는 것이 합리적 일 수 있습니다.

href="/css/scriptname/versionNumber.css" 

실제로 파일을 생성하거나 URL을 다시 작성해야하므로 더 많은 작업이 필요합니다.


4

캐시를 파열하기 위해 경로를 고유하게 만들기 위해 간단한 라이너 하나를 원했습니다. 이것은 나를 위해 일했습니다.

<script src="scripts/main.js?bust_js_cache=<%=System.IO.File.GetLastWriteTime(Server.MapPath("scripts/main.js")).ToString("HH:mm:ss")%>" type="text/javascript"></script>

페이지에 마지막으로로드 된 이후 파일이 수정 된 경우 브라우저는 업데이트 된 파일을 가져옵니다.

파일 에서 last modified스탬프를 생성하고 .js액세스하기 쉽지 않을 수있는 버전 대신 거기에 삽입합니다.

<script src="scripts/main.js?bust_js_cache=10:18:38" type="text/javascript"></script>

또 다른 옵션은 파일의 체크섬을 가져 오는 것입니다.


1
이 작업을 수행하는 가장 쉬운 방법이며 아마도 가장 낮은 오버 헤드 일 것입니다.
Tony Hinkle

1
완벽한 솔루션. 또한 Chrome 70, Firefox 63 및 IE 11을 테스트하여 캐싱이 실제로 작동하는지 확인했습니다. 그것은. 이것은 최소한 최신 버전의 브라우저에서 파일의 새 버전에 대한 캐싱 만 파열시킵니다. 다른 곳에서 일부 브라우저는 쿼리 문자열 (?)을 사용하여 모든 파일을 다시로드한다는 언급을 들었습니다. 그럴 수도 있고 Safari와 Opera에서도 여전히 사실 일 수도 있습니다. DK.
Brad Mathews

3

다음은 ASP.NET 5 / MVC 6 / vNext에서 작동하는 접근 방식입니다 .

1 단계 : 이 스레드의 다른 답변과 유사하게 파일의 마지막 쓰기 시간을 반환하는 클래스를 만듭니다. 이를 위해서는 ASP.NET 5 (또는 기타) 종속성 주입이 필요합니다.

public class FileVersionService
{
    private IHostingEnvironment _hostingEnvironment;
    public FileVersionService(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    public string GetFileVersion(string filename)
    {
       var path = string.Format("{0}{1}", _hostingEnvironment.WebRootPath, filename);
       var fileInfo = new FileInfo(path);
       var version = fileInfo.LastWriteTimeUtc.ToString("yyyyMMddhhmmssfff");
       return version;
     }
}

2 단계 : startup.cs 내에 삽입 할 서비스를 등록합니다 .

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<FileVersionService>();
    ...
}

3 단계 : ASP.NET 5에서는 다음과 같이 _Layout.cshtml 과 같은 레이아웃보기에 서비스를 직접 삽입 할 수 있습니다 .

@inject Namespace.Here.FileVersionService fileVersionService
<!DOCTYPE html>
<html lang="en" class="@ViewBag.HtmlClass">
<head>
    ...
    <link href="/css/styles.css?v=@fileVersionService.GetFileVersion("\\css\\styles.css")" rel="stylesheet" />
    ...
</head>
<body>
    ...
</body>

물리적 경로를 더 잘 결합하고 구문과 더 일관된 스타일로 파일 이름을 처리하기 위해 수행 할 수있는 몇 가지 마무리 작업이 있지만 이것이 시작점입니다. 사람들이 ASP.NET 5로 이동하는 데 도움이되기를 바랍니다.


이 동작은 실제로
기본적으로

3

내 aspnet MVC 4 사이트에서 약간 다른 기술을 사용했습니다.

_ViewStart.cshtml :

@using System.Web.Caching
@using System.Web.Hosting
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    PageData.Add("scriptFormat", string.Format("<script src=\"{{0}}?_={0}\"></script>", GetDeployTicks()));
}

@functions
{

    private static string GetDeployTicks()
    {
        const string cacheKey = "DeployTicks";
        var returnValue = HttpRuntime.Cache[cacheKey] as string;
        if (null == returnValue)
        {
            var absolute = HostingEnvironment.MapPath("~/Web.config");
            returnValue = File.GetLastWriteTime(absolute).Ticks.ToString();
            HttpRuntime.Cache.Insert(cacheKey, returnValue, new CacheDependency(absolute));
        }
        return returnValue;
    }
}

그런 다음 실제보기에서 :

 @Scripts.RenderFormat(PageData["scriptFormat"], "~/Scripts/Search/javascriptFile.min.js")

3

<?php $rand_no = rand(10000000, 99999999)?> <script src="scripts/myjavascript.js?v=<?=$rand_no"></script>

이것은 모든 브라우저에서 나를 위해 작동합니다. 여기서는 PHP를 사용하여 임의의 번호를 생성했습니다. 자신 만의 서버 측 언어를 사용할 수 있습니다 .`


좋은 대답이지만 Adam이 설명한 내용을 고려하지 않으면 ASP MVC가 약간 문제가 될 수 있습니다. MVC 5로 작업하는 경우 번들 폴더가 인식하지 못하기 때문입니다.하지만 제안 해 주셔서 감사합니다!
Federico Navarrete

2

위의 답변 에서 시작 하여 도우미가 CSS 파일로도 작동하도록 코드를 약간 수정하고 빌드 할 때뿐만 아니라 파일을 변경할 때마다 버전을 추가합니다.

public static class HtmlHelperExtensions
{
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename)
    {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    public static MvcHtmlString IncludeVersionedCss(this HtmlHelper helper, string filename)
    {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<link href='" + filename + version + "' type ='text/css' rel='stylesheet'/>");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;
        var physicalPath = context.Server.MapPath(filename);
        var version = "?v=" +
        new System.IO.FileInfo(physicalPath).LastWriteTime
        .ToString("yyyyMMddHHmmss");
        context.Cache.Add(physicalPath, version, null,
          DateTime.Now.AddMinutes(1), TimeSpan.Zero,
          CacheItemPriority.Normal, null);

        if (context.Cache[filename] == null)
        {
            context.Cache[filename] = version;
            return version;
        }
        else
        {
            if (version != context.Cache[filename].ToString())
            {
                context.Cache[filename] = version;
                return version;
            }
            return context.Cache[filename] as string;
        }
    }
}

1

아래와 같이 파일 수정 시간 가져 오기

private static string GetLastWriteTimeForFile(string pathVal)
    {
        return System.IO.File.GetLastWriteTime(HostingEnvironment.MapPath(pathVal)).ToFileTime().ToString();
    }

이것을 쿼리 문자열로 입력과 함께 추가하십시오.

public static string AppendDateInFile(string pathVal)
    {
        var patheWithDate = new StringBuilder(pathVal);
        patheWithDate.AppendFormat("{0}x={1}",
                               pathVal.IndexOf('?') >= 0 ? '&' : '?',
                               GetLastWriteTimeForFile(pathVal));
        return patheWithDate.ToString();
    }

마크 업에서 이것을 호출하십시오.

MVC 확장 도우미 접근 방식

확장 방법 추가

namespace TNS.Portal.Helpers
{
    public static class ScriptExtensions
    {
        public static HtmlString QueryStringScript<T>(this HtmlHelper<T> html, string path)
        {
            var file = html.ViewContext.HttpContext.Server.MapPath(path);
            DateTime lastModified = File.GetLastWriteTime(file);
            TagBuilder builder = new TagBuilder("script");
            builder.Attributes["src"] = path + "?modified=" + lastModified.ToString("yyyyMMddhhmmss");
            return new HtmlString(builder.ToString());
        }

       public static HtmlString QueryStringStylesheet<T>(this HtmlHelper<T> html, string path)
       {
        var file = html.ViewContext.HttpContext.Server.MapPath(path);
        DateTime lastModified = File.GetLastWriteTime(file);
        TagBuilder builder = new TagBuilder("link");
        builder.Attributes["href"] = path + "?modified=" + lastModified.ToString("yyyyMMddhhmmss");
        builder.Attributes["rel"] = "stylesheet";
        return new HtmlString(builder.ToString());
      }

    }
}

web.config에이 네임 스페이스 추가

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="TNS.Portal" />
        <add namespace="TNS.Portal.Helpers" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

보기에서 사용

@Html.QueryStringScript("/Scripts/NPIAjaxCalls.js")
@Html.QueryStringStylesheet("/Content/StyledRadio.css")

1

단순화 된 사전 제안 및 .NET Web Forms 개발자를위한 코드 제공.

리소스에 대한 파일 경로에서 상대 ( "~ /") 및 절대 URL을 모두 허용합니다.

다음과 같은 정적 확장 클래스 파일을 넣으십시오.

public static string VersionedContent(this HttpContext httpContext, string virtualFilePath)
{
    var physicalFilePath = httpContext.Server.MapPath(virtualFilePath);
    if (httpContext.Cache[physicalFilePath] == null)
    {
        httpContext.Cache[physicalFilePath] = ((Page)httpContext.CurrentHandler).ResolveUrl(virtualFilePath) + (virtualFilePath.Contains("?") ? "&" : "?") + "v=" + File.GetLastWriteTime(physicalFilePath).ToString("yyyyMMddHHmmss");
    }
    return (string)httpContext.Cache[physicalFilePath];
}

그런 다음 마스터 페이지에서 다음과 같이 호출하십시오.

<link type="text/css" rel="stylesheet" href="<%= Context.VersionedContent("~/styles/mystyle.css") %>" />
<script type="text/javascript" src="<%= Context.VersionedContent("~/scripts/myjavascript.js") %>"></script>

너무 좋은 접근!
Federico Navarrete

0

위의 답변을 바탕으로 CSS 및 JS 파일 작업을위한 작은 확장 클래스를 작성했습니다.

public static class TimestampedContentExtensions
{
    public static string VersionedContent(this UrlHelper helper, string contentPath)
    {
        var context = helper.RequestContext.HttpContext;

        if (context.Cache[contentPath] == null)
        {
            var physicalPath = context.Server.MapPath(contentPath);
            var version = @"v=" + new FileInfo(physicalPath).LastWriteTime.ToString(@"yyyyMMddHHmmss");

            var translatedContentPath = helper.Content(contentPath);

            var versionedContentPath =
                contentPath.Contains(@"?")
                    ? translatedContentPath + @"&" + version
                    : translatedContentPath + @"?" + version;

            context.Cache.Add(physicalPath, version, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero,
                CacheItemPriority.Normal, null);

            context.Cache[contentPath] = versionedContentPath;
            return versionedContentPath;
        }
        else
        {
            return context.Cache[contentPath] as string;
        }
    }
}

다음과 같이 작성하는 대신 :

<link href="@Url.Content(@"~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content(@"~/Scripts/bootstrap.min.js")"></script>

이제 다음과 같이 작성할 수 있습니다.

<link href="@Url.VersionedContent(@"~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.VersionedContent(@"~/Scripts/bootstrap.min.js")"></script>

즉 단순히 교체 Url.Content와 함께 Url.VersionedContent.

생성 된 URL은 다음과 같습니다.

<link href="/Content/bootstrap.min.css?v=20151104105858" rel="stylesheet" type="text/css" />
<script src="/Scripts/bootstrap.min.js?v=20151029213517"></script>

확장 클래스를 사용하는 경우 실제 파일이 아니므로 MapPath호출이 작동하지 않는 경우 오류 처리를 추가 할 수 있습니다 contentPath.


0

각 페이지를 수정하지 않고 동일한 작업을 수행하기 위해 비슷한 방법을 사용합니다. PreRender 이벤트가 마스터 파일에 추가되었습니다. 내 논리를 한곳에 유지하고 js 및 css 파일 모두에 적용 할 수 있습니다.

protected void Page_PreRender(object sender, EventArgs e)
    {
        HtmlLink link = null;
        LiteralControl script = null;


        foreach (Control c in Header.Controls)
        {
            //StyleSheet add version
            if (c is HtmlLink)
            {
                link = c as HtmlLink;


                if (link.Href.EndsWith(".css", StringComparison.InvariantCultureIgnoreCase))
                {
                    link.Href += string.Format("?v={0}", ConfigurationManager.AppSettings["agVersion"]);
                }

            }

            //Js add version
            if (c is LiteralControl)
            {
                script = c as LiteralControl;

                if (script.Text.Contains(".js"))
                {
                    var foundIndexes = new List<int>();


                    for (int i = script.Text.IndexOf(".js\""); i > -1; i = script.Text.IndexOf(".js\"", i + 1))
                    {

                        foundIndexes.Add(i);
                    }

                    for (int i = foundIndexes.Count - 1; i >= 0; i--)
                    {

                        script.Text = script.Text.Insert(foundIndexes[i] + 3, string.Format("?v={0}", ConfigurationManager.AppSettings["agVersion"]));
                    }
                }

            }

        }
    }

0

Scripts 또는 Styles의 DefaultTagFormat 속성을 재정의 할 수 있습니다.

Scripts.DefaultTagFormat = @"<script src=""{0}?v=" + ConfigurationManager.AppSettings["pubversion"] + @"""></script>";
Styles.DefaultTagFormat = @"<link href=""{0}?v=" + ConfigurationManager.AppSettings["pubversion"] + @""" rel=""stylesheet""/>";

0

내 ASP.Net Ajax 응용 프로그램에서이 문제를 해결하기 위해 확장을 만든 다음 마스터 페이지에서 호출했습니다.

자세한 내용은 링크 를 참조하십시오 .


0

아래 개념으로 .net 응용 프로그램에서 CSS 버전 관리를 구현하는 쉽고 스마트 한 방법입니다. 백엔드 코드를 작성할 필요가 없습니다.

<link href="<%="../../App_Themes/Base/css/main.css?v="+ DateTime.Now.ToString("yyyyMMddhhmmss") +""%>" rel="stylesheet" />

이것은 파일이 전혀 변경되지 않은 경우에도 모든 페이지 렌더링에서 강제로 다운로드됩니다.
Thanasis Ioannidis

@ThanasisIoannidis 파일이 정기적으로 변경되는 곳에서 사용할 수 있습니다. 또 다른 옵션은 web.config에 appVersion 키를 추가하고 파일 이름 ..과 함께 사용하는 것입니다.하지만 prod 용 애플리케이션을 출시 할 때 업데이트해야합니다.
SantoshK

-1

이 방법의 주요 문제는 주로 CSS 또는 js 파일을 변경할 때마다 코드에서 버전 번호를 업데이트해야한다는 점입니다.

이를 수행하는 더 좋은 방법은 다음과 같이 각 css 또는 js 파일에 보장 된 고유 매개 변수를 설정하는 것입니다.

<script src="scripts/myjavascript.js?_=<%=DateTime.Now.Ticks%>" type="text/javascript"></script>
<link href="styles/mystyle.css?_=<%=DateTime.Now.Ticks%>" rel="stylesheet" type="text/css" />

이렇게하면 파일이 매번 서버에서 요청됩니다. 이는 또한 해당 파일이 캐시되지 않고 매번 불필요한 대역폭을 사용하기 때문에 페이지로드시 사이트 성능이 떨어짐을 의미합니다.

기본적으로 변경 사항이있을 때마다 버전 번호를 업데이트해야한다는 것을 기억할 수 있다면 작업 방식을 잊을 수 있습니다.


9
그리고 엄청난 양의 대역폭도 사용합니다.
Darren Kopp

2
맞습니다. 각 페이지가로드 될 때마다 새 버전의 JS를 원하지는 않습니다. 실제로 업데이트 된 버전이있을 때마다 브라우저가 새 버전을 찾길 원합니다.
kingdango

이것은 개발 중에 50KB css 파일의 임시 솔루션에 완벽하게 허용됩니다. +1
Colbs 2014-06-23

-2

ASP.NET 페이지의 경우 다음을 사용하고 있습니다.

전에

<script src="/Scripts/pages/common.js" type="text/javascript"></script>

후 (강제 재 장전)

 <script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>

DateTime.Now.Ticks 추가는 매우 잘 작동합니다.


예, 문제는 대역폭과 관련이 있습니다. 위의 설명에서와 같이 stackoverflow.com/a/2185918/59508
kiev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.