我寫過一個圖像處理程序,它通過在滿足特定條件時發送304來實現客戶端緩存。爲了訪問不同的照片或登錄的人自己的照片,我們將處理程序按以下方式放在不同的頁面上。ASHX通用處理程序在刷新頁面之前不會觸及(使用F5或刷新按鈕)
<img src="EmployeePhoto.ashx" />
<img src="EmployeePhoto.ashx?self" />
<img src="EmployeePhoto.ashx?default" />
的問題是,如果我通過點擊鏈接在第二次的影像已被緩存的頁面後,它並沒有擊中處理器(調試器不會命中)訪問任何頁面。但是,如果我用F5或刷新按鈕刷新該頁面,那麼只有它碰到處理程序並顯示我想要顯示的內容。
只有當我試圖用另一個參數如「& date =」+ CurrentDate來訪問它時,它會觸發處理程序,但它會殺死緩存的目的。
<img src="EmployeePhoto.ashx?default&date=03/31/14 00:00:00" /> //or something like that
我知道代碼沒有問題,因爲它在被命中時效果很好。無論如何,這是代碼。
public void ProcessRequest(HttpContext context)
{
var isDefault = true;
var textIfModifiedSince = context.Request.Headers["If-Modified-Since"];
context.Response.ClearHeaders();
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMonths(6));
try
{
var isOwn = false;
var user = /*Gets logged in user instance from service*/;
var employeeId = 0;
if (context.Request.QueryString.Count > 0)
{
if(context.Request.QueryString[0] == "self")
{
if (user != null)
{
employeeId = Convert.ToInt32(user.EmployeeId);
isOwn = true;
}
}
else if (!int.TryParse(context.Request.QueryString[0], out employeeId))
employeeId = 0;
}
else
{
if (user != null)
{
employeeId = Convert.ToInt32(user.EmployeeId);
isOwn = true;
}
}
if (user != null && employeeId != 0)
{
var employee = GetEmployee(employeeId);
if (
(!string.IsNullOrEmpty(textIfModifiedSince) && employee.Modify_Date == null)
|| !string.IsNullOrEmpty(textIfModifiedSince)
&& employee.Modify_Date != null
&& employee.Modify_Date <= Convert.ToDateTime(textIfModifiedSince).AddMinutes(1))
{
isDefault = false;
context.Response.Cache.SetLastModified(Convert.ToDateTime(textIfModifiedSince));
context.Response.Status = "304 Not Modified";
HttpContext.Current.ApplicationInstance.CompleteRequest();
return;
}
if (
employee != null
&& !string.IsNullOrEmpty(employee.Picture)
&& (isOwn || employee.LocationID != null)
&& (isOwn || HasRequiredRoles))
{
var path = context.Server.MapPath("~//" + EmployeePhotoPath);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var fileName = employee.Picture;
var destinationPath =
context.Server.MapPath("~//" + EmployeePhotoPath).ToString(CultureInfo.InvariantCulture);
if (File.Exists(destinationPath + fileName))
{
isDefault = false;
context.Response.Cache.SetLastModified(employee.Modify_Date > DateTime.Now ? DateTime.Now : (employee.Modify_Date ?? DateTime.Now));
context.Response.ContentType = GetContentType(employee.Picture);
context.Response.WriteFile(EmployeePhotoPath + employee.Picture);
HttpContext.Current.ApplicationInstance.CompleteRequest();
return;
}
isDefault = false;
DownloadFromSFTP(path, employee.Picture, user, employeeId.ToString(CultureInfo.InvariantCulture));
context.Response.Cache.SetLastModified(employee.Modify_Date > DateTime.Now ? DateTime.Now : (employee.Modify_Date ?? DateTime.Now));
context.Response.ContentType = GetContentType(employee.Picture);
context.Response.WriteFile(EmployeePhotoPath + employee.Picture);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
}
catch (Exception ex)
{
Log.Debug("Photo Handler Failed.", ex);
}
finally
{
if (isDefault)
{
if (!string.IsNullOrEmpty(textIfModifiedSince))
{
context.Response.Cache.SetLastModified(Convert.ToDateTime(textIfModifiedSince));
context.Response.Status = "304 Not Modified";
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
context.Response.Cache.SetLastModified(DateTime.Now);
context.Response.ContentType = GetContentType("images/avatar.gif");
context.Response.WriteFile("images/avatar.gif");
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
}
ADDITION: 在以下情況下會發生此問題。
- 用戶通過訪問EmployeePhoto.ashx訪問圖像?Eid的= 20349
- 管理員再次改變爲Eid的照片= 20349
- 用戶訪問的頁面(未清涼但一些鏈路訪問頁)
頁面上的緩存圖像帶來舊圖像,如果它已經擊中處理程序,那麼情況已經在那裏處理,但它沒有,頁面顯示緩存版本本身。我只在鉻上檢查過。
如果你想要加載圖像,而不是隻是第一次在[這篇文章]有一些想法(http://stackoverflow.com/questions/13369379/how-do-i-expire-a-cached -image-without-hitting-f5) – Pete
我訪問了@Pete這個問題,我已經嘗試過那裏提到的解決方案。但它會殺死緩存的目的,因爲每次它將發佈一個新的「If-Modified-Since」 –
這是一個「Bekaar sawaal」,順便說一句,「614」kese karli itni聲譽? –