2012-02-23 16 views
6

क्या किसी को पता है कि मेरे पृष्ठ पर कुकीज़ क्यों है, आउटपुट कैश काम नहीं करता है!एएसपीनेट आउटपुट कैश और कुकीज़

उदाहरण पेज

Partial Class ct 
    Inherits System.Web.UI.Page 

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load 
     Dim rc As New Random() 
     Dim rn As Integer 
     rn = rc.Next() 
     rndout.InnerHtml = rn.ToString 

     Response.Cookies("sym")("hello") = "world" 
     Response.Cookies("sym").Expires = DateTime.Now.AddDays(370) 
     Response.Cookies("sym").Domain = Application.Get("cookieurl") 


    End Sub 
End Class 

पीछे

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ct.aspx.vb" Inherits="ct" %> 
<%@ OutputCache Duration="600" Location="Server" VaryByParam="none" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <h1>Cache test</h1> 
     <p id="rndout" runat="server"></p> 
    </div> 
    </form> 
</body> 
</html> 

उदाहरण कोड जब आईआईएस 6 या 7 इस कैश, हालांकि अगर मैं बाहर टिप्पणी नहीं करता 3 Response.Cookies लाइनों यह करता है के लिए तैनात किया।

जब वीएस में चलाया जाता है तो यह दोनों तरीकों से ठीक काम करता है।

क्या iis/web.config आदि में कुछ सेटिंग है, जबकि output.cache सेट करते समय आउटपुट कैश की अनुमति देता है। मैं समझता हूं कि कुकी सामग्री को कैश किया जाएगा साथ ही यह कैश किए गए http प्रतिक्रिया का केवल एक हिस्सा है।

धन्यवाद

Symeon।

+0

आप पूर्व संध्या किया आर समाधान मिला? – Allov

+1

मुझे एक ही चीज़ सच साबित हुई लेकिन किसी भी आधिकारिक दस्तावेज़ का सामना नहीं किया है। स्पष्ट रूप से यह बताते हुए कि यह काम नहीं करता है। – JNappi

+0

@Allov, देरी के लिए खेद है - नहीं मुझे कोई समाधान नहीं मिला है। कुकी से छुटकारा पाने के अलावा या यदि मुझे कुकी की ज़रूरत है तो मैं उस पृष्ठ पर एक स्क्रिप्ट टैग या 0x0 छवि जोड़ सकता हूं जो केवल कुकी सेट करता है। –

उत्तर

4

आप सर्वर पक्ष पर इसे कैश करने का प्रयास करते हैं, और साथ ही आप क्लाइंट पर कुकी सेट करने का प्रयास करते हैं - यह एक साथ काम नहीं कर रहा है।

क्यों: जब आप सर्वर पर कैश पर एक पृष्ठ सेट करते हैं तो कैश किए गए संस्करण को सेवा के दौरान कोड पीछे नहीं चलाया जाता है (क्लाइंट को भेजें)। यह सर्वर पर कैशिंग का मुद्दा है। कुछ भी चलाने के लिए और कैश से इसे देने के लिए नहीं है।

शायद आपको केवल शीर्ष पर कैश सेट करना होगा और सर्वर पर पूरा पृष्ठ कैश नहीं करना होगा।

+1

मैं एएसपीनेट में एक पेज बना रहा हूं जिसमें एक कुकी है। मैं चाहता हूं कि आईआईएस इस पृष्ठ को कैश करे और पीछे कोड न चलाएं। मैं ऐसा करने के लिए मानक .NET कोड का उपयोग कर रहा हूँ। हालांकि ऐसा लगता है कि अगर मैं outputcook निर्देश का उपयोग करता हूं तो मैं प्रतिक्रिया.cookie का उपयोग करता हूं। यह .NET के भीतर किसी भी तरह से प्रलेखित नहीं है। असल में एक लेख कह रहा है कि यदि आप कुकीज वाले पेज को कैश करते हैं तो कुकीज़ को भी कैश किया जाता है। मुझे अच्छी तरह से पता है कि कुकी http हेडर का हिस्सा है और इसलिए कैश किया जाएगा। मेरा सवाल यह है कि यदि आईआईएस/web.config आदि में कोई सेटिंग है जो इसे सक्षम बनाता है। यह कैसीनी –

+0

@ साइमन में चलाए जाने पर ठीक काम करता है यह आपके द्वारा करने की कोशिश करने वाली तार्किक (छोटी गाड़ी) नहीं है। आप एक उपयोगकर्ता को एक कुकी सेट करते हैं, अगले उपयोगकर्ता के बारे में क्या कोई कुकी सेट नहीं है? क्लाइंट पर कुकी सेट - आपने सर्वर कैश के साथ क्लाइंट कैश को मिश्रित किया है। जब कुकी क्लाइंट की तरफ सर्वर पर नहीं होती है तो कुकी भी कैश पर होती है – Aristos

+1

जो कोई भी पृष्ठ पर जाता है उसे कुकी दी जाएगी, चाहे वह मौजूद हो या नहीं। एक कुकी सिर्फ http शीर्षलेख में पाठ है। मैं देख सकता हूं कि यह भ्रमित क्यों हो सकता है, लेकिन मैंने सोचा कि वहां कुछ विन्यास होना चाहिए क्योंकि यह कहता है कि वे कहां परस्पर अनन्य हैं, और यह कैसिनी में ठीक काम करता है।इसे देखें-http: //support.microsoft.com/kb/917072 ऐसा लगता है जैसे कुकी को कैशिंग करना चाहिए क्योंकि वे इसे रोकने के लिए एक कार्यवाही देते हैं। –

0

मुझे एक ही समस्या थी और मैंने स्थान = "सर्वर एंड क्लाइंट" सेट करके अरिस्टोस द्वारा दिए गए परिदृश्य का परीक्षण किया और यह काम करता है। अगर मैं केवल स्थान = "सर्वर" का उपयोग करता हूं तो यह काम नहीं करता है।

+0

आपके मामले में, केवल क्लाइंट (HTTP प्रतिक्रिया हेडर कैशिंग) काम करेगा। यदि आप अपनी प्रतिक्रिया में कुकीज़ सेट करते हैं तो पृष्ठ आउटपुट सर्वर पर कैश नहीं किया जाएगा। – d4n3

1

यह देखने के लिए जांचें कि क्या आप .NET 2.0 SP1 चला रहे हैं और यदि आपने MS11-100 (दिसंबर 2012 को जारी किया) लागू किया है।

हमें इसी तरह के मुद्दों का सामना करना पड़ा और माइक्रोसॉफ्ट सपोर्ट तक पहुंचने लगा। उन्होंने MS11-100 ब्रेक आउटपुट कैशिंग की पुष्टि की लेकिन दावा किया कि यह डिजाइन द्वारा किया गया था (पैच में तय सुरक्षा भेद्यता की प्रकृति के कारण) और वर्तमान में आउटपुट कैश कार्यक्षमता को पुनर्स्थापित करने के लिए कुछ भी नहीं किया जा रहा है।

एक साधारण परीक्षण: यदि आपको लगता है कि आपके पास पैच स्थापित है, तो बस उस पैच को अनइंस्टॉल करें और रीबूट करें। आपको देखना चाहिए कि आउटपुट कैशिंग काम करना शुरू कर देता है। मुझे नहीं लगता कि कोई भी सुरक्षा प्रभाव के कारण उत्पादन समाधान के रूप में इसकी सिफारिश करेगा, इसलिए समस्या को अलग करने के साधनों के रूप में इसका उपयोग करें।

हमने एक नए ढांचे का परीक्षण करना समाप्त कर दिया है (आपको 4.0 पर जाना है; 3.5 सिर्फ 2.0 ढांचे का विस्तार है और अपने आप पर एक स्टैंडअलोन फ्रेमवर्क नहीं है) और, सभी संकलन त्रुटियों को हल करने के बाद, आउटपुट कैशिंग तुरंत काम करना शुरू कर दिया ।

हमने कुकीज़ के साथ बातचीत करने के तरीके को बदलने पर भी काम किया ताकि हम 2.0 ढांचे पर रह सकें (आखिरकार, पूरे पूरे एप्लिकेशन का परीक्षण करने के बजाय हमारे कुकी हैंडलर कक्षाओं का परीक्षण करना आसान होना चाहिए)। कई बाधाएं हैं और अंतिम उत्पाद "हैक" की मांग की गई है, जो कि बिना किसी जाने के थे।

2

यह .NET ढांचे के विभिन्न संस्करणों के कारण होता है। असल में, कुछ संस्करण कभी कुकी सेट के साथ पृष्ठ कैश नहीं करेंगे।

See this blog posting

+0

स्टैक ओवरफ़्लो में आपका स्वागत है! आपका उत्तर पोस्ट करने के लिए धन्यवाद! कृपया सावधानीपूर्वक [स्व-संवर्धन पर अक्सर पूछे जाने वाले प्रश्न] (http://stackoverflow.com/faq#promotion) को पढ़ना सुनिश्चित करें। यह भी ध्यान रखें कि यह * आवश्यक * है कि जब भी आप अपनी साइट/उत्पाद से लिंक करते हैं तो आप एक अस्वीकरण पोस्ट करते हैं। –

-1

एक समाधान है जो कुछ परिस्थितियों में काम कर सकते हैं नहीं है: तो कुकी पेज कोड पर निर्भर नहीं करता है लेकिन कुछ स्टैंडअलोन कोड के साथ गणना की जा सकती है, तो आप Application_EndRequest Application_EndRequest के बाद संसाधित किया जाता है में कुकी सेट कर सकते हैं आउटपुट कैश और इसलिए कैश को कुकी के साथ संग्रहीत किया जाता है लेकिन क्लाइंट को अनुरोध वितरित करने से पहले सेट कुकी हेडर जोड़ा जाता है।

+0

मैंने इस विधि को आजमाया और प्रतिक्रिया प्राप्त करने के बाद "हेडर संशोधित नहीं कर सकता" प्राप्त हुआ। – WiseGuyEh

2

इस समस्या में थोड़ा सा शोध करने के बाद, मुझे समस्या को समझने और काम करने के लिए आया।

कारण उत्पादन कैश कुकीज़

साथ अच्छा नहीं चलता है तो कारण उत्पादन कैश कुकीज़ के साथ एक प्रतिक्रिया को कैश नहीं होगा कि एक कुकी उपयोगकर्ता-विशिष्ट हो सकता है (उदाहरण के लिए प्रमाणीकरण, विश्लेषणात्मक ट्रैकिंग, है आदि।)। यदि HttpCookie.Shareable = false संपत्ति के साथ एक या अधिक कुकीज़, तो आउटपुट कैश प्रतिक्रिया को बिना दर्द रहित मानता है।

एक कैश्ड प्रतिक्रिया

यह वह जगह है जहां इसे पाने के मुश्किल से कुकी सहित । आउटपुट कैश प्रतिक्रिया हेडर और सामग्री को एक साथ कैश करता है और उपयोगकर्ता को वापस भेजने से पहले इन्हें संशोधित करने के लिए कोई हुक प्रदान नहीं करता है। हालांकि, मैं एक कैश्ड प्रतिक्रिया के हेडर संशोधित करने की क्षमता प्रदान करने के लिए निम्न कस्टम उत्पादन कैश प्रदाता लिखा था इससे पहले कि वे उपयोगकर्ता के लिए वापस भेज दिया जाता है (nuget पैकेज Fasterflect की आवश्यकता है):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Caching; 
using System.Web; 
using System.Web.Caching; 
using Fasterflect; 

namespace CustomOutputCache 
{ 
    /// <summary> 
    /// An output cache provider that has ability to modify the http header collection before a cached response is served back to the user. 
    /// </summary> 
    public class HeaderModOutputCacheProvider : OutputCacheProvider 
    { 
     private static readonly Type OutputCacheEntryType, HttpCachePolicySettingsType; 
     private static readonly Type[] ParameterTypes; 

     public static event EventHandler<CachedRequestEventArgs> RequestServedFromCache; 

     static HeaderModOutputCacheProvider() 
     { 
      var systemWeb = typeof(HttpContext).Assembly; 
      OutputCacheEntryType = systemWeb.GetType("System.Web.Caching.OutputCacheEntry"); 
      HttpCachePolicySettingsType = systemWeb.GetType("System.Web.HttpCachePolicySettings"); 
      ParameterTypes = new[]{ 
       typeof(Guid), 
       HttpCachePolicySettingsType, 
       typeof(string), 
       typeof(string) , 
       typeof(string[]), 
       typeof(int), 
       typeof(string), 
       typeof(List<HeaderElement>), 
       typeof(List<ResponseElement>) 
      }; 
     } 

     private readonly ObjectCache _objectCache; 

     public HeaderModOutputCacheProvider() 
     { 
      _objectCache = new MemoryCache("output-cache"); 
     } 

     #region OutputCacheProvider implementation 

     public override object Get(string key) 
     { 
      var cachedValue = _objectCache.Get(key); 

      if (cachedValue == null) 
       return null; 

      if (cachedValue.GetType() != OutputCacheEntryType) 
       return cachedValue; 

      var cloned = CloneOutputCacheEntry(cachedValue); 

      if (RequestServedFromCache != null) 
      { 
       var args = new CachedRequestEventArgs(cloned.HeaderElements); 
       RequestServedFromCache(this, args); 
      } 

      return cloned; 
     } 

     public override object Add(string key, object entry, DateTime utcExpiry) 
     { 
      _objectCache.Set(key, entry, new CacheItemPolicy { AbsoluteExpiration = utcExpiry }); 
      return entry; 
     } 

     public override void Set(string key, object entry, DateTime utcExpiry) 
     { 
      _objectCache.Set(key, entry, new CacheItemPolicy { AbsoluteExpiration = utcExpiry }); 
     } 

     public override void Remove(string key) 
     { 
      _objectCache.Remove(key); 
     } 

     #endregion 

     private IOutputCacheEntry CloneOutputCacheEntry(object toClone) 
     { 
      var parameterValues = new[] 
      { 
       toClone.GetFieldValue("_cachedVaryId", Flags.InstancePrivate), 
       toClone.GetFieldValue("_settings", Flags.InstancePrivate), 
       toClone.GetFieldValue("_kernelCacheUrl", Flags.InstancePrivate), 
       toClone.GetFieldValue("_dependenciesKey", Flags.InstancePrivate), 
       toClone.GetFieldValue("_dependencies", Flags.InstancePrivate), 
       toClone.GetFieldValue("_statusCode", Flags.InstancePrivate), 
       toClone.GetFieldValue("_statusDescription", Flags.InstancePrivate), 
       CloneHeaders((List<HeaderElement>)toClone.GetFieldValue("_headerElements", Flags.InstancePrivate)), 
       toClone.GetFieldValue("_responseElements", Flags.InstancePrivate) 
      }; 

      return (IOutputCacheEntry)OutputCacheEntryType.CreateInstance(
       parameterTypes: ParameterTypes, 
       parameters: parameterValues 
      ); 
     } 

     private List<HeaderElement> CloneHeaders(List<HeaderElement> toClone) 
     { 
      return new List<HeaderElement>(toClone); 
     } 
    } 

    public class CachedRequestEventArgs : EventArgs 
    { 
     public CachedRequestEventArgs(List<HeaderElement> headers) 
     { 
      Headers = headers; 
     } 
     public List<HeaderElement> Headers { get; private set; } 

     public void AddCookies(HttpCookieCollection cookies) 
     { 
      foreach (var cookie in cookies.AllKeys.Select(c => cookies[c])) 
      { 
       //more reflection unpleasantness :(
       var header = cookie.CallMethod("GetSetCookieHeader", Flags.InstanceAnyVisibility, HttpContext.Current); 
       Headers.Add(new HeaderElement((string)header.GetPropertyValue("Name"), (string)header.GetPropertyValue("Value"))); 
      } 
     } 
    } 
} 

आप इसे तार होगा इस तरह:

<system.web> 
    <caching> 
     <outputCache defaultProvider="HeaderModOutputCacheProvider"> 
     <providers> 
      <add name="HeaderModOutputCacheProvider" type="CustomOutputCache.HeaderModOutputCacheProvider"/> 
     </providers> 
     </outputCache> 
    </caching> 
    </system.web> 

और इस तरह इसका इस्तेमाल कर सकते कुकीज़ सम्मिलित करने के लिए:

HeaderModOutputCacheProvider.RequestServedFromCache += RequestServedFromCache; 

HeaderModOutputCacheProvider.RequestServedFromCache += (sender, e) => 
{ 
    e.AddCookies(new HttpCookieCollection 
    { 
     new HttpCookie("key", "value") 
    }); 
}; 
संबंधित मुद्दे