【问题标题】:Google can't crawl generated CSS and JS paths originating from Custom outputcacheGoogle 无法抓取源自自定义输出缓存的生成的 CSS 和 JS 路径
【发布时间】:2017-06-26 12:25:36
【问题描述】:

我已经为我的网站设置了自定义输出缓存。一切都按预期工作,我可以看到包含二进制文件的缓存文件夹。当我访问该站点时,我会获取缓存页面并按应有的方式呈现。

问题是当我尝试使用谷歌站长工具渲染页面时,谷歌无法访问BundleConfig~/bundles/styles/maincss/中生成的css路径,javascript路径也是如此。当我访问这两个路径时​​,我会看到缩小的 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();
        }
    }
}

【问题讨论】:

  • @mjwills 我用代码更新了问题。
  • 如果你在FileStream fileStream = File.OpenWrite(filePath); 之前和之后都放了Thread.Sleep(5000) 刷新你的浏览器缓存,重新启动 IIS 然后在两个不同的浏览器(比如 Chrome 和 Firefox)中同时加载相同的 JS 资源您是否会因为两件事同时尝试写入文件而收到错误消息?
  • @mjwills 我没有收到错误,Google 无法访问它。我在网站管理员工具中启动了几次抓取,但仍然无法访问它。我可以用我的浏览器访问它。当 Google 访问它时,它应该从同一个缓存中读取,而不是向缓存中写入任何内容。
  • @mjwills 我得到进程无法访问文件'C:\Users\Idan\Desktop\projectx\projectx_project\projectxx\Cache\a2$bundles$styles$maincss$',因为它正在被使用由另一个进程。'
  • 我也得到 System.NotSupportedException: 'The given path's format is not supported.'。在 Mozilla Firefox 中使用。

标签: c# asp.net caching outputcache


【解决方案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.

【讨论】:

    猜你喜欢
    • 2021-06-08
    • 2012-05-20
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多