1

最近、Gravatar の優れたフォールバックとして Robohash をインストールしました。

ここに画像の説明を入力

http://static2.scirra.net/avatars/128/5df4bf5d460c9497fdb35578e923ad1f.png

ご覧のとおり、ロボハッシュは陽気に素晴らしいものであり、静的ドメインから提供されます。URL は実際に書き換えられます。

<action type="Rewrite" url="gravatar.ashx?hash={R:2}&amp;size={R:1}" appendQueryString="false" />

そして、同じ web.config ファイルにキャッシュ プロファイルがあります。

<staticContent>
    <clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
</staticContent>
<caching>
    <profiles>
        <add extension=".ashx" policy="CacheForTimePeriod"  kernelCachePolicy="DontCache" duration="01:00:00" />
        <add extension=".png" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
        <add extension=".jpg" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
        <add extension=".gif" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
        <add extension=".ico" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
    </profiles>
</caching>

gravatar.ashx ファイルで適切な測定を行うために、キャッシュ ポリシーも設定します。

<%@ WebHandler Language="C#" Class="GravatarImage" %>

using System;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;

public class GravatarImage : IHttpHandler {

    public void ProcessRequest (HttpContext context) {

        // Adds document content type        
        context.Response.Cache.SetCacheability(HttpCacheability.Public);
        context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(60));
        context.Response.Cache.SetMaxAge(new TimeSpan(1, 0, 0));
        context.Response.AddHeader("Last-Modified", DateTime.Now.ToLongDateString());

        // Get params and send initial request to gravatar
        string Hash = context.Request.QueryString["hash"];
        string Size = context.Request.QueryString["size"];
        string URL = "http://www.gravatar.com/avatar/" + Hash + "?r=pg&s=" + Size + "&d=404";

        // Make request to gravatar
        bool Fetched = makeAvatarRequest(URL);

        // Backup to robo hash
        if (!Fetched)
        {
            URL = "http://robohash.org/" + Hash + ".png?size=" + Size + "x" + Size + "&bgset=bg2";
            Fetched = makeAvatarRequest(URL);
        }

        // Fallback if gravatar doesn't match and robohash is down
        if (!Fetched)
        {

        }

        // Cache this handler response for 1 hour.
        HttpCachePolicy c = context.Response.Cache;
        c.SetCacheability(HttpCacheability.Public);
        c.SetMaxAge(new TimeSpan(1, 0, 0));
    }

    // Attempt a request for avatar
    private bool makeAvatarRequest(string URL)
    {        
        try
        {
            WebRequest request = WebRequest.Create(URL);
            using (WebResponse response = request.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    displayImage(responseStream);
                    return true;
                }
            }
        }
        catch (WebException ex)
        {
            return false;
        }
    }

    // Display the image from stream
    private void displayImage(Stream stream)
    {
        HttpContext.Current.Response.ContentType = "image/png";
        Image img = Image.FromStream(stream);
        MemoryStream temp = new MemoryStream();
        img.Save(temp, ImageFormat.Png);
        byte[] buffer = temp.GetBuffer();
        HttpContext.Current.Response.OutputStream.Write(buffer, 0, buffer.Length);

        img.Dispose();
        temp.Dispose();        
    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

下部で Response.cache AND CachePolicy を使用していることに注意してください

YSlow を使用すると、有効期限のないこれらのアバターを除いて、ページ上のすべての画像に将来の有効期限があります。ページがリクエストされるたびに、ページが再度取得されます。

スクリプトの考え方は、外部 URL からアバターを取得し、それを 1 時間キャッシュすることです。その後、当社のウェブサイトから提供されます。

誰か助けてくれませんか?キャッシュなしでアバターが使用されているページの例: http://www.scirra.com/forum/construct-in-ludum-dare-21_topic44523.html

4

1 に答える 1

1

ハンドラーを使用しているため、独自のコードでキャッシュ ヘッダーを処理する必要があります。つまり、304 応答も返します。そのため、ファイルに対してヘッダーの日付を確認し、必要に応じて 304 を返します。

一部の画像ハンドラーの開始時に、次のようなコードがあります。

var lastModified = this.LastModifiedFileTime(path);
var isNotModified = this.WriteConditional304(context, lastModified);
if (isNotModified)
    return;

使用される 2 つの方法は、大まかに次のようになります。

protected bool WriteConditional304(HttpContext context, DateTime lastWrite)
    {
        if (context.Request.Headers[since] != null || context.Request.Headers[eTag] != null)
        {
            try
            {
                DateTime date = context.Request.Headers[since] != null ? DateTime.Parse(context.Request.Headers[since]) : new DateTime(long.Parse(context.Request.Headers[eTag]));

                if (lastWrite <= date)
                {
                    Write304(context);
                    return true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        return false;
    }



protected DateTime LastModifiedFileTime(string path)
    {
        FileInfo fi = new FileInfo(path);
        var modificationTime = fi.LastWriteTime;
        // negates the smaller parts of the date as the header doesnt carry them
        var date = new DateTime(modificationTime.Year, modificationTime.Month, modificationTime.Day, modificationTime.Hour,
            modificationTime.Minute, modificationTime.Second);
        return date;
    }
于 2011-09-14T01:37:57.557 に答える