Earlier I was asking the question how to set up both httpexpires and cachecontrol headers
I think I kind of found the answer
<clientCache cacheControlCustom="public" httpExpires="Tue, 19 Jan 2038 03:14:07 GMT" cacheControlMaxAge="12:00:00" cacheControlMode="UseExpires" />
Now i am not receiving 500 internal error for image requests.
But now I have a new question
Looks like If I set cacheControlMode="UseExpires" it will use httpExpires as content expiratoin but if I set cacheControlMode="UseMaxAge" it will use cacheControlMaxAge as content expiration. So still not clear how to set both cacheControlMaxAge and httpExpires? Is it possible?
Related
As far as my research goes, there are several steps in order to make sure that browser caching is disabled. These HTTP headers must be set:
Cache-Control: no-cache, no-store, must-revalidate, proxy-revalidate
Pragma: no-cache
Expires: -1
Last-Modified: -1
I have found out that this can be done in two ways:
Way One: use the web.config file
<add name="Cache-Control" value="no-store, no-cache,
must-revalidate, proxy-revalidate"/>
<add name="Pragma" value="no-cache" />
<add name="Expires" value="-1" />
<add name="Last-Modified" value="-1" />
Way Two: use the meta tags in _Layout.cshtml
<meta http-equiv="Cache-Control" content="no-cache, no-store,
must-revalidate, proxy-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="Expires" content="-1" />
My Question: which is the better approach? Or, alternatively, are they equally acceptable? How do these all relate to different platforms? Which browsers would honor what headers?
In addition, please feel free to add anything I've missed, if any.
Okay folks, seems I made a blunt mistake. There is a best way and that is not using meta tags. The only correct way is to use headers.
Why not use meta tags? Because they are guaranteed not to work with
proxies, which do not read (not supposed to read) the HTML body; they
rely on the headers.
When both Cache-Control and Expires are present, Cache-Control takes
precedence. Source here.
Cache-Control general-header field is used to specify directives that
MUST be obeyed by all caching mechanisms along the request/response
chain. Source here.
I have a project in "ASP.NET MVC 5" and use "less" for files "bootstrap", use the following libraries:
http://www.nuget.org/packages/BundleTransformer.Core/
http://www.nuget.org/packages/BundleTransformer.Less/
http://www.nuget.org/packages/JavaScriptEngineSwitcher.Core/
http://www.nuget.org/packages/JavaScriptEngineSwitcher.Msie/
http://www.nuget.org/packages/MsieJavaScriptEngine/
in my BundleConfig.css I have this:
BundleTable.EnableOptimizations = false;
bundles.UseCdn = true;
CssTransformer cssTransformer = new CssTransformer();
JsTransformer jsTransformer = new JsTransformer();
NullOrderer nullOrderer = new NullOrderer();
Bundle cssBundle = new CustomStyleBundle("~/bundles/css");
cssBundle.Include("~/Content/bootstrap/bootstrap.less");
cssBundle.Include("~/Content/font-awesome.css");
cssBundle.Include("~/Content/site.less");
cssBundle.Transforms.Add(cssTransformer);
cssBundle.Orderer = nullOrderer;
bundles.Add(cssBundle);
in my environment works fine and if I use IIS works fine, but when I make the publush in "Windows Azure" for "less" files get this error:
HTTP/1.1 500 Internal Server Error
Content-Length: 75
Content-Type: text/html
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Date: Wed, 21 May 2014 11:56:01 GMT
The page cannot be displayed because an internal server error has occurred.
Only with files less, others file like css o js return rigth
(I think I have another problem that does not display errors but that's another question). Web.config for error:
<system.web>
<customErrors mode="Off">
</customErrors>
edit
configuration for less in web.config like this template
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
<less>
<jsEngine name="MsieJsEngine" />
</less>
<core>
<css>
<minifiers>
<add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
</minifiers>
<translators>
<add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
<add name="LessTranslator" type="BundleTransformer.Less.Translators.LessTranslator, BundleTransformer.Less" /></translators>
</css>
<js>
<minifiers>
<add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
</minifiers>
<translators>
<add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
</translators>
</js>
</core>
</bundleTransformer>
<jsEngineSwitcher xmlns="http://tempuri.org/JavaScriptEngineSwitcher.Configuration.xsd">
<core>
<engines>
<add name="MsieJsEngine" type="JavaScriptEngineSwitcher.Msie.MsieJsEngine, JavaScriptEngineSwitcher.Msie" />
</engines>
</core>
</jsEngineSwitcher>
Remove from your code the following line:
cssBundle.Transforms.Add(cssTransformer);
This line is redundant and may cause errors when using the CustomStyleBundle class.
BundleTransformer only works while bundling. In other words, the *.less files are never actually used by the client, but rather, transformed into CSS and then combined and minified before actually being sent down. Requesting the *.less file directly won't work unless IIS has a mime-type to handle it, but even setting that doesn't really help you, because again, IIS is not typically serving this file.
I used YSlow to test an ASP.NET MVC web site and I got the error:
"Add Expiry Headers" for the following items:
(no expires) http://www.mydomain.pt/assets/logo.png
(no expires) http://www.mydomain.pt/favicon-196x196.png
(2013/12/30) http://www.mydomain.pt/file/e6fb9d2a-668b-423a-9120-0b34228f296c
What is strange is that I addressed these issues. For static I used:
CORRECTED
<system.webServer>
<clientCache setEtag="false" cacheControlMode="UseMaxAge" cacheControlMaxAge="60.00:00:00" />
</system.webServer>
And for the file, returned by an action, I have:
[Route("file/{identifier:guid}"), HttpGet, OutputCache(Duration = 1200, Location = OutputCacheLocation.Client, VaryByParam = "identifier")]
public virtual ActionResult Get(Guid identifier, String n = null) {
}
Does anyone knows why I still have no cache on these items?
Am I missing something?
Thank You,
Miguel
Use following syntax:
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="60.00:00:00" />
</staticContent>
</system.webserver>
Compressing static files doesn't have anything to do with expiration headers. Compression is related to GZip.
The reason the .png files do not have the Expiry header that you are setting in the action method, is that MVC is not being used to serve the static files, so it will not set the headers.
Add expires header to images
I have done xml parsing before using some guides from Ray Wenderlich, but those are usually for when there are multiple items involved. I am working on having an app simply display weather conditions at a given time, and the feed's XML just has conditions for time checked. Here is the feed in question:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
<title>Yahoo! Weather - Montgomery, AL</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Montgomery__AL/*http://weather.yahoo.com/forecast/USAL0375_f.html</link>
<description>Yahoo! Weather for Montgomery, AL</description>
<language>en-us</language>
<lastBuildDate>Thu, 03 Jan 2013 11:55 am CST</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Montgomery" region="AL" country="United States"/>
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
<yweather:wind chill="43" direction="0" speed="5" />
<yweather:atmosphere humidity="66" visibility="10" pressure="30.26" rising="2" />
<yweather:astronomy sunrise="6:46 am" sunset="4:52 pm"/>
<image>
<title>Yahoo! Weather</title>
<width>142</width>
<height>18</height>
<link>http://weather.yahoo.com</link>
<url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
</image>
<item>
<title>Conditions for Montgomery, AL at 11:55 am CST</title>
<geo:lat>32.38</geo:lat>
<geo:long>-86.3</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Montgomery__AL/*http://weather.yahoo.com/forecast/USAL0375_f.html</link>
<pubDate>Thu, 03 Jan 2013 11:55 am CST</pubDate>
<yweather:condition text="Mostly Cloudy" code="28" temp="46" date="Thu, 03 Jan 2013 11:55 am CST" />
<description><![CDATA[
<img src="http://l.yimg.com/a/i/us/we/52/28.gif"/><br />
<b>Current Conditions:</b><br />
Mostly Cloudy, 46 F<BR />
<BR /><b>Forecast:</b><BR />
Thu - Partly Cloudy. High: 50 Low: 31<br />
Fri - Sunny. High: 57 Low: 35<br />
<br />
Full Forecast at Yahoo! Weather<BR/><BR/>
(provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>
]]></description>
<yweather:forecast day="Thu" date="3 Jan 2013" low="31" high="50" text="Partly Cloudy" code="30" />
<yweather:forecast day="Fri" date="4 Jan 2013" low="35" high="57" text="Sunny" code="32" />
<guid isPermaLink="false">USAL0375_2013_01_04_7_00_CST</guid>
</item>
</channel>
</rss>
Basically, all I need for the app is the current temperature and conditions, which under the item tag is contained within yweather:conditions tag. Using GDataXML, what would be simplest way of getting this info and setting an NSString equal to it?
Right now, I'm using some complex stuff from Ray's tutorial with asihttprequest and blocks for sorting and putting it all into an NSMutableArray, but I'm fairly certain it doesn't need be that complex now.
I like TBXML for straightforward parsing: http://www.tbxml.co.uk/TBXML/TBXML_Free.html .
I'm working with WebHarvest to fetch data from a site that requires logging in.
It's setup like this:
Page 1 = Login page
Page 2 = Login validation page
Page 3 = Statistics page
On page 2 a cookie is set. When monitoring the opening of Page 2 with Firebug I get these headers:
Connection Keep-Alive
Content-Type text/html; charset=UTF-8
Date Tue, 23 Oct 2012 18:25:12 GMT
Keep-Alive timeout=15, max=100
Server Apache/2.0.64 (Win32) JRun/4.0 SVN/1.3.2 DAV/2
Set-Cookie SESSION=hej123;expires=Thu, 16-Oct-2042 18:25:12 GMT;path=/
Transfer-Encoding chunked
When calling the same page with WebHarvest I only get these headers:
Date=Tue, 23 Oct 2012 18:31:51 GMT
Server=Apache/2.0.64 (Win32) JRun/4.0 SVN/1.3.2 DAV/2
Transfer-Encoding=chunked
Content-Type=text/html; charset=UTF-8
It seems that three headers (Set-Cookie, Connection and Keep-Alive) are not found by WebHarvest. Page 1, 2 and 3 are dummys so no actual validation is done. The cookie is always set on the serverside for Page 2.
Here is the WebHarvest code I am currently using:
<var-def name="content2">
<html-to-xml>
<http method="post" url="http://myurl.com/page2.cfm">
<http-param name="Login">sigge</http-param>
<http-param name="Password">hej123</http-param>
<http-param name="doLogin">Logga in</http-param>
<loop item="currField">
<list>
<var name="ctxtNewInputs" />
</list>
<body>
<script><![CDATA[
item = (NvPair) currField.getWrappedObject();
SetContextVar("itemName", item.name);
SetContextVar("itemValue", item.value);
]]></script>
<http-param name="${item.name}"><var name="itemValue" /></http-param>
</body>
</loop>
<script><![CDATA[
String keys="";
for(int i=0;i<http.headers.length;i++) {
keys+=(http.headers[i].key + "=" + http.headers[i].value +"\n---\n");
}
SetContextVar("myCookie", keys);
]]></script>
<file action="write" path="c:/kaka.txt">
<var name="myCookie"/>
</file>
</http>
</html-to-xml>
</var-def>
Edit:
when checking I noticed that the cookie is set in WebHarvest, even if the http header can't be found programatically. Is it possible that some response headers are hidden from usage?
Does anyone know a work-around for this problem?
Thank you and best regards,
SiggeLund
The way to get http header value into user-defined variable scoped for the whole config is the following:
<http url="your.url.here" method="GET">
<!--Any settings you apply for the POST/GET call-->
</http>
<!--Now you've got your http object you are going to get header value from -->
<!--At it simplest the acquisition of value goes like the below-->
<var-def name="fifth_header_val">
<script return="http.headers[5].value"/>
</var-def>
The above is just to give a clue. You can iterate over http.headers index and collect keys and values you need for your particular task.