2017-06-26 100 views
0

我已經爲我的網站設置了自定義輸出緩存。一切按預期工作,我可以看到與二進制文件的緩存文件夾。當我訪問該網站時,我得到了緩存的頁面,並且它應該呈現。Google無法抓取源自Custom outputcache的生成的CSS和JS路徑

的問題是,當我嘗試使用谷歌網站管理員工具來渲染頁面,谷歌無法訪問在BundleConfig ~/bundles/styles/maincss/產生的生成的css路徑,也是一樣的JavaScript path.`。當我訪問這兩條路徑時,我會看到縮小的JS和CSS文件,瀏覽器確實正確地呈現頁面。

這就提出了一個問題,因爲現在當我使用移動的測試工具測試頁面,我得到的網頁並不適合移動設備。由於某些原因,Google無法訪問這些路徑,但是當我在網站站長工具中運行網絡爬網時,它確實爲用戶提供了良好的體驗,但不適用於Google bot。

這工作時,我不使用自定義輸出緩存,只有默認的輸出緩存。

不知道如何解決這個問題。

定製的輸出代碼:

Web.config文件:

</connectionStrings> 
<appSettings> 
    <add key="CacheLocation" value="~/Cache"/> 
</appSettings> 
<system.web> 
    <caching> 
    <outputCache defaultProvider="FileCache"> 
     <providers> 
     <add name="FileCache" type="ProjectX.FileCacheProvider"/> 
    </providers> 
    </outputCache> 
</caching> 

緩存類:

using System; 
using System.Configuration; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Web; 
using System.Web.Caching; 

namespace ProjectX 
{ 
    [Serializable] 
    public class CacheItem 
    { 
     public object Item { get; set; } 
     public DateTime Expiry { get; set; } 
    } 

    public class FileCacheProvider : OutputCacheProvider 
    { 
     private string CacheLocation 
     { 
      get 
      { 
       string strCacheLocation = ConfigurationManager.AppSettings["CacheLocation"]; 
       strCacheLocation = HttpContext.Current.Server.MapPath(strCacheLocation); 
       return strCacheLocation + @"\"; 
      } 
     } 


     private string GetFullPathForKey(string key) 
     { 
      string temp = key.Replace('/', '$'); 
      return CacheLocation + temp; 
     } 

     public override object Add(string key, object entry, DateTime utcExpiry) 
     { 
      object obj = this.Get(key); 
      if (obj != null) 
      { 
       return obj; 
      } 
      else 
      { 
       this.Set(key, entry, utcExpiry); 
       return entry; 
      } 
     } 

     public override void Remove(string key) 
     { 
      string filePath = GetFullPathForKey(key); 
      if (File.Exists(filePath)) 
      { 
       File.Delete(filePath); 
      } 
     } 

     public override object Get(string key) 
     { 
      string filePath = GetFullPathForKey(key); 
      if (!File.Exists(filePath)) 
      { 
       return null; 
      } 
      CacheItem item = null; 
      FileStream fileStream = File.OpenRead(filePath); 
      BinaryFormatter formatter = new BinaryFormatter(); 
      item = (CacheItem)formatter.Deserialize(fileStream); 
      fileStream.Close(); 
      if (item == null || item.Expiry <= DateTime.UtcNow) 
      { 
       Remove(key); 
       return null; 
      } 
      return item.Item; 
     } 



     public override void Set(string key, object entry, DateTime utcExpiry) 
     { 
      string filePath = GetFullPathForKey(key); 
      CacheItem item = new CacheItem { Expiry = utcExpiry, Item = entry }; 
      FileStream fileStream = File.OpenWrite(filePath); 
      BinaryFormatter formatter = new BinaryFormatter(); 
      formatter.Serialize(fileStream, item); 
      fileStream.Close(); 
     } 
    } 
} 
+0

@mjwills我用代碼更新了問題。 –

+0

如果你把'Thread.sleep代碼(5000)'之前和之後'的FileStream FILESTREAM = File.OpenWrite(文件路徑);'清空瀏覽器緩存,重新啓動IIS,然後在兩個單獨的瀏覽器加載相同的JS的資源(比如瀏覽器和Firefox)的同時你會得到一個錯誤,因爲有兩樣東西試圖同時寫入文件? – mjwills

+0

@mjwills我沒有收到錯誤,Google無法訪問它。我多次在網站站長工具中發起抓取,但仍無法訪問它。我可以用我的瀏覽器訪問它。當Google訪問它時,應該從相同的緩存中讀取它,而不是寫入任何內容到緩存。 –

回答

1

如果您希望繼續沿着這條道路(我假定你已經使用https://weblogs.asp.net/gunnarpeipman/asp-net-4-0-writing-custom-output-cache-providers爲您起點?),您將需要更改GetFullPathForKey,以便它生成有效的文件名。 How to remove illegal characters from path and filenames?可能會幫助你做到這一點。您還需要更改代碼,以便在兩個線程同時嘗試寫入同一文件時不會發生切換。另外,您真的應該介紹使用MemoryCache以避免在每次發生Get調用您的課程時碰到文件系統。 這將是很多工作。

我會建議考慮這些的NuGet包作爲替代。他們這樣做的東西開箱,並是行之有效的:

或者只是捶在與緩存協助Web服務器前面的反向代理 - 例如http://mikehadlow.blogspot.com.au/2013/05/the-benefits-of-reverse-proxy.html