gpt4 book ai didi

c# - 利用 IIS 中的浏览器缓存(谷歌页面速度问题)

转载 作者:IT王子 更新时间:2023-10-29 03:49:52 26 4
gpt4 key购买 nike

有几个关于利用浏览器缓存的问题,但我没有发现任何关于如何在 ASP.NET 应用程序中执行此操作的有用信息。 Google 的 Pagespeed 告诉我们这是性能最大的问题。
到目前为止,我在我的 web.config 中做了这个:

<system.webServer>
<staticContent>
<!--<clientCache cacheControlMode="UseExpires"
httpExpires="Fri, 24 Jan 2014 03:14:07 GMT" /> -->
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.24:00:00" />
</staticContent>
</system.webServer>

注释代码有效。我可以将过期 header 设置为将来的某个特定时间,但我无法设置 cacheControlMaxAge 来设置从现在开始缓存静态内容的天数。这是行不通的。我的问题是:

我怎样才能做到这一点?
我知道可以只为特定文件夹设置缓存,这将是一个很好的解决方案,但它也不起作用。应用程序托管在 Windows Server 2012 上,在 IIS8 上,应用程序池设置为经典。

在网络配置中设置此代码后,页面速度为 72(之前为 71)。 50 个文件未缓存。 (现在 49 岁)我想知道为什么,我刚刚意识到实际上缓存了一个文件(svg 文件)。不幸的是 png 和 jpg 文件不是。
这是我的 web.config
<?xml version="1.0" encoding="utf-8"?>

<configuration>
<configSections>
<section name="exceptionManagement" type="Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManagerSectionHandler,Microsoft.ApplicationBlocks.ExceptionManagement" />
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E34" requirePermission="false" allowDefinition="Everywhere" />
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>
</configSections>

<exceptionManagement mode="off">
<publisher mode="off" assembly="Exception" type="blabla.ExceptionHandler.ExceptionDBPublisher" connString="server=188......;database=blabla;uid=blabla;pwd=blabla; " />
</exceptionManagement>
<location path="." inheritInChildApplications="false">
<system.web>
<httpHandlers>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler,System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e34" validate="false" />
<add verb="GET" path="Image.ashx" type="blabla.WebComponents.ImageHandler, blabla/>"
<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory" />
<add verb="*" path="*.jpg" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.js" type="System.Web.StaticFileHandler" />
<add verb="*" path="*.gif" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.css" type="System.Web.StaticFileHandler" />
</httpHandlers>
<compilation defaultLanguage="c#" targetFramework="4.5.1" />
<trace enabled="false" requestLimit="100" pageOutput="true" traceMode="SortByTime" localOnly="true"/>
<authentication mode="Forms">
<forms loginUrl="~/user/login.aspx">
<credentials passwordFormat="Clear">
<user name="blabla" password="blabla" />
</credentials>
</forms>
</authentication>
<authorization>
<allow users="*" />
</authorization>
<sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20" />
<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="en-GB" uiCulture="en-GB" />
<xhtmlConformance mode="Transitional" />
<pages controlRenderingCompatibilityVersion="4.5" clientIDMode="AutoID">
<namespaces>

</namespaces>
<controls>
<add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" />
</controls>
</pages>
<webServices>
<protocols>
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
</webServices>
</system.web>
</location>
<appSettings>

</appSettings>
<connectionStrings>

</connectionStrings>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="200000" />
</webServices>
</scripting>
</system.web.extensions>
<startup>
<supportedRuntime version="v2.0.50727" />
<supportedRuntime version="v1.1.4122" />
<supportedRuntime version="v1.0.3705" />
</startup>
<system.webServer>


<rewrite>
<providers>
<provider name="ReplacingProvider" type="ReplacingProvider, ReplacingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5ab632b1f332b247">
<settings>
<add key="OldChar" value="_" />
<add key="NewChar" value="-" />
</settings>
</provider>
<provider name="FileMap" type="DbProvider, Microsoft.Web.Iis.Rewrite.Providers, Version=7.1.761.0, Culture=neutral, PublicKeyToken=0525b0627da60a5e">
<settings>
<add key="ConnectionString" value="server=;database=blabla;uid=blabla;pwd=blabla;App=blabla"/>
<add key="StoredProcedure" value="Search.GetRewriteUrl"/>
<add key="CacheMinutesInterval" value="0"/>
</settings>
</provider>
</providers>
<rewriteMaps configSource="rewritemaps.config" />
<rules configSource="rewriterules.config" />
</rewrite>
<modules>
<remove name="ScriptModule" />
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3456AD264E35" />
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
</modules>
<handlers>
<add name="Web-JPG" path="*.jpg" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="Web-CSS" path="*.css" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="Web-GIF" path="*.gif" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="Web-JS" path="*.js" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
<httpErrors errorMode="DetailedLocalOnly" existingResponse="Auto">
<remove statusCode="404" subStatusCode="-1"/>
<remove statusCode="500" subStatusCode="-1"/>
<error statusCode="404" path="error404.htm" responseMode="File"/>
<error statusCode="500" path="error.htm" responseMode="File"/>
</httpErrors>
</system.webServer>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="soapBinding_AdriagateService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" messageEncoding="Text">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None" />
</binding>
</basicHttpBinding>
<netTcpBinding>
<binding name="NetTcpBinding_ITravellerService" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="blabla" bindingConfiguration="soapBinding_blabla" contract="" Address="blabla" name="blabla" />
<endpoint address="blabla" binding="basicHttpBinding" bindingConfiguration="soapBinding_IImagesService"
contract="ImagesService.IImagesService" name="soapBinding_IImagesService"/>
<identity>
<servicePrincipalName value="blabla"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
</system.web>
<elmah>
<security allowRemoteAccess="false" />
</elmah>
<location path="elmah.axd" inheritInChildApplications="false">
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>

</system.web>
<system.webServer>
<handlers>
<add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
</handlers>
</system.webServer>
</location>
</configuration>

编辑:
如果我设置了确切的到期日期,则缓存有效,但不适用于 jpg、gif ....仅适用于 png

EDIT2:
如果我在这里设置 cacheControlCustom="public" :
<clientCache cacheControlCustom="public" 
cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />

缓存正在工作,但 仍然 不适用于 jpeg 和 gif;它只适用于 svgs 和 pngs。

最佳答案

大多数浏览器缓存问题可以通过查看响应头来解决(可以在谷歌浏览器开发者工具中完成)。

enter image description here

现在clientCache您的 web.config 部分文件应该将您的输出缓存设置为最大年龄,如下图所示设置了 max-age86400这是 1 天(以秒为单位)。

这是此设置的 web.config 片段。

<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="1.00:00:00" />

现在很好,响应头有一个 max-ageCache-Control 上设置的属性标题。所以浏览器应该缓存内容。嗯,这基本上是正确的,但有些浏览器需要设置另一个标志。特别是 public为缓存控制 header 设置的标志。这可以通过使用 cacheControlCustom 轻松添加。 web.config 中的属性.这是一个例子。
<clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="1.00:00:00" />

现在,当我们重试页面并检查标题时。

enter image description here

现在从上图可以看出,我们现在有了值 public, max-age=86400 .所以我们的浏览器拥有缓存资源所需的一切。现在检查谷歌浏览器的标题和网络选项卡将帮助我们。

这是对文件的第一个请求..注意文件没有被缓存......
enter image description here

现在让我们回到这个页面( 注意: 不要刷新页面,我们稍后会讨论)。您将看到现在从缓存返回的响应(如圆圈所示)。

enter image description here

现在,如果我使用 F5 或使用浏览器刷新功能刷新页面会发生什么。等等..哪里去了 (from cache)走。
enter image description here

那么在谷歌浏览器(不确定其他浏览器)中使用刷新按钮将重新下载静态资源,而不管缓存 header 如何(请在此处插入说明)。这意味着已重新检索资源并发送了最大年龄 header 。

现在在完成上面的所有解释之后,一定要测试 怎么样您正在监视缓存 header 。

更新

根据您的评论,您说您有一个名为 IHttpHandler 的通用处理程序( Image.ashx )内容类型为 image/jpg .现在您可能期望默认行为是缓存此处理程序。但是 IIS 看到扩展名 .ashx (正确地)作为动态脚本并且不受缓存的影响,而无需在代码本身中显式设置缓存 header 。

现在这是您需要小心的地方,通常是 IHttpHandlers实际上不应缓存,因为它们通常提供动态内容。现在,如果该内容不太可能更改,您可以直接在代码中设置缓存 header 。这是在 IHttpHandlers 中设置缓存头的示例使用 Response语境。
context.Response.ContentType = "image/jpg";

context.Response.Cache.SetMaxAge(TimeSpan.FromDays(1));
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetSlidingExpiration(true);

context.Response.TransmitFile(context.Server.MapPath("~/out.jpg"));

现在查看我们在 Cache 上设置一些属性的代码。属性(property)。为了获得所需的响应,我设置了属性。
  • context.Response.Cache.SetMaxAge(TimeSpan.FromDays(1));告诉输出缓存设置 max-age= Cache-Control的一部分标题要1 future 的一天(86400 秒)。
  • context.Response.Cache.SetCacheability(HttpCacheability.Public);告诉输出缓存设置 Cache-Control标题到 public .这非常重要,因为它告诉浏览器缓存对象。
  • context.Response.Cache.SetSlidingExpiration(true);告诉输出缓存确保它正在设置 max-age= Cache-Control的一部分标题正确。如果不设置滑动过期时间,IIS 输出缓存将忽略最大年龄 header 。把这些放在一起给了我这个结果。

  • output cache from ashx file

    正如我上面所说,您可能不想缓存 .ashx文件,因为它们通常提供动态内容。但是,如果该动态内容在给定时间内不太可能发生变化,您可以使用上述方法来交付您的 .ashx文件。

    现在结合上面列出的过程,您还可以设置 ETag (请参阅 wiki)缓存 header 的组件,以便浏览器可以验证由自定义字符串传递的内容。维基指出:

    An ETag is an opaque identifier assigned by a web server to a specific version of a resource found at a URL. If the resource content at that URL ever changes, a new and different ETag is assigned.



    所以这实际上是浏览器的某种唯一标识,用于识别响应中传递的内容。通过提供这个标题,浏览器在下一次重新加载时会发送一个 If-None-Match带有 ETag 的标题从上次回复来看。我们可以修改我们的处理程序来检测 If-None-Match标题并将其与我们自己生成的 Etag 进行比较.现在没有精确的科学来生成 ETags但一个好的经验法则是提供一个标识符,它很可能只定义一个实体。在这种情况下,我喜欢使用连接在一起的两个字符串,例如。
    System.IO.FileInfo file = new System.IO.FileInfo(context.Server.MapPath("~/saveNew.png"));
    string eTag = file.Name.GetHashCode().ToString() + file.LastWriteTimeUtc.Ticks.GetHashCode().ToString();

    在上面的代码片段中,我们正在从我们的文件系统加载一个文件(您可以从任何地方获取它)。然后我使用 GetHashCode()方法(在所有对象上)获取对象的整数哈希码。在示例中,我连接了文件名的哈希值,然后是上次写入日期。最后写入日期的原因是如果文件被更改,哈希码也会更改,从而使指纹不同。

    这将生成一个类似于 306894467-210133036 的哈希码。 .

    那么我们如何在我们的处理程序中使用它。下面是处理程序的新修改版本。
    System.IO.FileInfo file = new System.IO.FileInfo(context.Server.MapPath("~/out.png"));
    string eTag = file.Name.GetHashCode().ToString() + file.LastWriteTimeUtc.Ticks.GetHashCode().ToString();
    var browserETag = context.Request.Headers["If-None-Match"];

    context.Response.ClearHeaders();
    if(browserETag == eTag)
    {
    context.Response.Status = "304 Not Modified";
    context.Response.End();
    return;
    }
    context.Response.ContentType = "image/jpg";
    context.Response.Cache.SetMaxAge(TimeSpan.FromDays(1));
    context.Response.Cache.SetCacheability(HttpCacheability.Public);
    context.Response.Cache.SetSlidingExpiration(true);
    context.Response.Cache.SetETag(eTag);
    context.Response.TransmitFile(file.FullName);

    正如你所看到的,我已经改变了很多处理程序,但是你会注意到我们生成了 Etag散列,检查传入 If-None-Match标题。如果 etag 哈希值和 header 相等,那么我们通过返回状态码 304 Not Modified 告诉浏览器内容没有改变。 .

    接下来是相同的处理程序,只是我们添加了 ETag通过调用标题:
    context.Response.Cache.SetETag(eTag);

    当我们在浏览器中运行它时,我们得到了。

    Cache-Control with ETag

    您将从图像中看到(因为我确实更改了文件名),我们现在拥有缓存系统的所有组件。 ETag正在作为 header 传递,浏览器正在发送请求 header If-None-Match所以我们的处理程序可以相应地响应缓存文件的更改。

    关于c# - 利用 IIS 中的浏览器缓存(谷歌页面速度问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21074198/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com