ปิดใช้งานแคชเบราว์เซอร์สำหรับเว็บไซต์ ASP.NET ทั้งหมด


199

ฉันกำลังมองหาวิธีปิดใช้งานแคชเบราว์เซอร์สำหรับเว็บไซต์ ASP.NET MVC ทั้งหมด

ฉันพบวิธีต่อไปนี้:

Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
Response.Cache.SetNoStore();

และวิธีเมตาแท็ก (มันจะไม่ทำงานสำหรับฉันเนื่องจากการกระทำ MVC บางอย่างส่ง HTML / JSON บางส่วนผ่าน Ajax โดยไม่มี head, meta tag)

<meta http-equiv="PRAGMA" content="NO-CACHE">

แต่ฉันกำลังมองหาวิธีง่ายๆในการปิดการใช้งานแคชเบราว์เซอร์สำหรับเว็บไซต์ทั้งหมด


คำตอบ:


92
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();

คำขอทั้งหมดได้รับการส่งผ่าน default.aspx ก่อนดังนั้นสมมติว่าคุณสามารถป๊อปอัปในโค้ดด้านหลังได้


17
ฉันจะใส่ไว้ใน Global.asax.cs ใน Application_BeginRequest () ฉันไม่เชื่อสิ่ง default.aspx นี้ ... คำถามอื่น: สิ่งนี้มีความสำคัญเหนือกว่าแอตทริบิวต์ [OutputCache] หรือไม่
chris166

5
ฉันชอบความคิดในการสร้าง Global Action Filter เพียงแค่วางสิ่งนี้ในแบบนั้น ทำให้ไม่ต้องกังวลเกี่ยวกับ Default.aspx และ Global.asax
Keith Adler

13
การวางสิ่งนี้ไว้ใน Application_BeingRequest อาจทำให้เกิดปัญหาบางอย่าง หากรูปภาพของคุณกำหนดเส้นทางผ่านรันไทม์. net (ซึ่งอาจเกิดขึ้นได้หากคุณใช้การจับคู่สัญลักษณ์แทน URL ที่ดี) จะไม่มีการแคชรูปภาพในเบราว์เซอร์ วิธีนี้อาจช้าลงในการโหลดหน้าเว็บของคุณเนื่องจากคำขอแต่ละหน้าจะดาวน์โหลดรูปภาพทั้งหมดใหม่
herbrandson

4
การใช้อะไรก็ตามโดยทางโปรแกรมจะแทนที่แอตทริบิวต์ที่ประกาศไว้เสมอ กล่าวอีกนัยหนึ่งการใช้รหัสของ OP จะแทนที่แอตทริบิวต์ [OutputCache] ที่ประกาศไว้
เดฟสีดำ

มีความคิดเกี่ยวกับวิธีการทดสอบควันและตรวจสอบว่าแคชที่ปิดใช้งานทำงานได้จริง
paaone

366

สร้างคลาสที่สืบทอดจาก IActionFilter

public class NoCacheAttribute : ActionFilterAttribute
{  
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

จากนั้นจึงใส่คุณสมบัติที่จำเป็น ...

[NoCache]
[HandleError]
public class AccountController : Controller
{
    [NoCache]
    [Authorize]
    public ActionResult ChangePassword()
    {
        return View();
    }
}

19
แทนที่จะ HttpContext.Current.Response คุณน่าจะใช้ filterContext.HttpContext.Response เนื่องจาก HttpContext.Current จะส่งคืนวัตถุ pre-MVC HttpContext และ filterContext.HttpContext จะส่งกลับ มันเพิ่มความสามารถในการทดสอบและความมั่นคง
mkedobbs

5
IActionFilter มีการนำไปใช้กับ ActionFilterAttribute แล้วดังนั้นคุณไม่จำเป็นต้องทำซ้ำ
แอนดรูดาวี่

104
ใน ASP.NET MVC เวอร์ชันปัจจุบันคุณสามารถใช้ OutputCacheAttribute เพื่อป้องกันการแคช: [OutputCache (NoStore = true, Duration = 0, VaryByParam = "None")]
Ashley Tate

9
ฉันต้องการจะชี้ให้เห็นว่าฉันใช้เวลาหลายวันในการแก้ปัญหา "ใส่ไว้ในรหัสของคุณเพื่อหยุดการแคช" ภายใต้ดวงอาทิตย์สำหรับ ASP.NET MVC รวมถึงคำตอบที่ได้รับการยอมรับสำหรับคำถามนี้เพื่อประโยชน์ คำตอบนี้ - คุณลักษณะ - ทำงาน +1 ตัวแทนถ้าฉันทำได้ ...
Tom Kidd

5
คุณอาจต้องการเพิ่มif (filterContext.IsChildAction) return;ที่ด้านบน - ซึ่งจะป้องกันไม่ให้การกระทำภายนอกเป็น 'ไม่แคช' ถ้ามันเรียกว่าการกระทำของเด็กที่ตกแต่งด้วยNoCacheคุณลักษณะ ในคำอื่น ๆNoCacheแอตทริบิวต์จะไม่รั่วไหลไปสู่การกระทำอื่น ๆ หากพวกเขาดำเนินการกระทำของเด็ก นอกจากนี้ชื่อคลาสควรNoCacheAttributeสอดคล้องกับหลักการตั้งชื่อที่ยอมรับโดยทั่วไปสำหรับคุณลักษณะต่างๆ
Jakub Konecki

132

แทนที่จะใช้ของคุณเองเพียงใช้สิ่งที่มีให้สำหรับคุณ

ตามที่กล่าวไว้ก่อนหน้านี้อย่าปิดใช้งานการแคชสำหรับทุกสิ่ง ตัวอย่างเช่นสคริปต์ jQuery ที่ใช้อย่างมากใน ASP.NET MVC ควรถูกแคช อันที่จริงแล้วคุณควรจะใช้CDNสำหรับสิ่งเหล่านั้น แต่ประเด็นของฉันคือเนื้อหาบางส่วนควรถูกแคช

สิ่งที่ฉันพบว่าทำงานได้ดีที่สุดที่นี่แทนที่จะโรย [OutputCache] ทุกที่เพื่อใช้คลาส:

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class NoCacheController  : Controller
{
}

ตัวควบคุมทั้งหมดของคุณที่คุณต้องการปิดการใช้งานแคชนั้นสืบทอดมาจากตัวควบคุมนี้

หากคุณต้องการแทนที่ค่าเริ่มต้นในคลาส NoCacheController เพียงระบุการตั้งค่าแคชในวิธีการกระทำของคุณและการตั้งค่าในวิธีการดำเนินการของคุณจะมีความสำคัญกว่า

[HttpGet]
[OutputCache(NoStore = true, Duration = 60, VaryByParam = "*")]
public ViewResult Index()
{
  ...
}

4
@Ozziepeeps ความคิดเห็นของคุณไม่ถูกต้อง เอกสาร msdn หารือเกี่ยวกับการแคชของเบราว์เซอร์เช่นเดียวกับการทดสอบอย่างง่าย ๆ จะแสดงคุณลักษณะนี้เปลี่ยนหัวข้อการตอบสนองการควบคุมแคชเป็น "การควบคุมแคช: สาธารณะไม่มีที่เก็บ, max-age = 0" จาก "การควบคุมแคช: ส่วนตัว" ใช้คุณลักษณะ
Adam Tuliper - MSFT

2
fyi ด้วย - คุณสามารถควบคุมทั้งสามตำแหน่ง (เซิร์ฟเวอร์, พร็อกซี, ไคลเอนต์) ด้วยแอ็ตทริบิวต์นี้เพื่อให้สามารถควบคุมได้เกินแคชเซิร์ฟเวอร์ ดูasp.net/mvc/tutorials/…สำหรับรายละเอียดเพิ่มเติม
Adam Tuliper - MSFT

1
+1 "หากคุณต้องการแทนที่ค่าเริ่มต้นในคลาส NoCacheController เพียงระบุการตั้งค่าแคชในวิธีการกระทำของคุณและการตั้งค่าในวิธีการกระทำของคุณจะมีความสำคัญกว่า"
Korayem

2
โปรดทราบว่าถ้าคุณใช้[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]ในระดับชั้นคุณจะไม่สามารถมี PartialViews ในชั้นเรียนของคุณ
Vivian River

1
วิธี OutputCache ไม่ได้ป้องกันการแคช IE เมื่อมีสองเงื่อนไข: 1) การดำเนินการไม่มีพารามิเตอร์และ 2) การดำเนินการส่งคืนข้อความผ่านทางเนื้อหา (someText) เท่านั้น เมื่อฉันส่งคืน JSON และรับพารามิเตอร์การแคช IE จะแพ้อย่างเหมาะสม
Kasey Speakman

10

คุณอาจต้องการที่จะปิดการใช้งานเบราว์เซอร์แคชสำหรับทุกหน้าแสดงผลโดยตัวควบคุม (เช่น HTML หน้า) แต่เก็บแคชในสถานที่สำหรับทรัพยากรเช่นสคริปต์แผ่นสไตล์และภาพ หากคุณใช้ MVC4 + การรวมและการลดขนาดคุณจะต้องรักษาระยะเวลาแคชเริ่มต้นสำหรับสคริปต์และสไตล์ชีท (ระยะเวลาที่ยาวมากเนื่องจากแคชได้รับการทำให้ใช้งานไม่ได้ขึ้นอยู่กับการเปลี่ยนแปลง URL ที่ไม่ซ้ำกันตามเวลา)

ใน MVC4 + หากต้องการปิดใช้งานการแคชเบราว์เซอร์ในตัวควบคุมทั้งหมด แต่เก็บไว้เพื่อสิ่งใดก็ตามที่ไม่ได้รับการควบคุมโดยตัวควบคุมให้เพิ่มส่วนนี้ในFilterConfig.RegisterGlobalFilters:

filters.Add(new DisableCache());

กำหนดDisableCacheดังนี้

class DisableCache : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}

น่าเสียดายที่นี่ไม่ทำงานเนื่องจากกดปุ่มย้อนกลับหลังจากออกจากระบบจะแสดงหน้า
ᴍᴀᴛᴛʙᴀᴋᴇʀ

6

ฉันรู้ว่าคำตอบนี้ไม่เกี่ยวข้องกับคำถาม 100% แต่อาจช่วยคนอื่นได้

หากคุณต้องการปิดการใช้งานแคชเบราว์เซอร์สำหรับเว็บไซต์ ASP.NET MVC ทั้งหมดแต่คุณต้องการทำ TEMPORARILY นี้เป็นการดีกว่าที่จะปิดการใช้งานแคชในเบราว์เซอร์ของคุณ

นี่คือภาพหน้าจอใน Chrome


นี่คือสิ่งที่ฉันกำลังมองหา ... ในระหว่างการพัฒนาถ้าฉันเปลี่ยนไฟล์. js มันเป็นความเจ็บปวดครั้งใหญ่ที่จะเกิดขึ้นในทันทีเมื่อฉันมีปัญหาในการแก้ไขปัญหาเล็กน้อย / รีเฟรช / ทดสอบรอบ นี่มันยอดเยี่ยมมากขอบคุณ! เพิ่งทำให้ชีวิตลูกค้าของฉันดีขึ้นมากขึ้นง่ายขึ้น
jleach

2

ฉันใช้คำตอบก่อนหน้านี้ทั้งหมดแล้วและยังมีมุมมองเดียวที่ทำงานไม่ถูกต้อง

มันเปิดออกชื่อของมุมมองที่ฉันมีปัญหากับชื่อ 'ล่าสุด' เห็นได้ชัดว่านี่ทำให้เบราว์เซอร์ Internet Explorer สับสน

หลังจากที่ฉันเปลี่ยนชื่อมุมมอง (ในตัวควบคุม) เป็นชื่ออื่น (ฉันเลือกเป็น 'ล่าสุด 5') โซลูชันด้านบนก็เริ่มทำงานได้


0

คุณสามารถลองรหัสด้านล่างในไฟล์ Global.asax

protected void Application_BeginRequest()
    {
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));
        Response.Cache.SetNoStore();
    }

-1

UI

<%@ OutPutCache Location="None"%>
<%
    Response.Buffer = true;
    Response.Expires = -1;
    Response.ExpiresAbsolute = System.DateTime.Now.AddSeconds(-1);
    Response.CacheControl = "no-cache";
%>

พื้นหลัง

Context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Expires = -1;          
Response.Cache.SetNoStore();

1
ต้องการคำอธิบายร้อยแก้วแม้ว่าจะถูกต้องทางเทคนิคแล้ว
ก็ตาม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.