9

cache-controlヘッダーが に設定されている場合、Chrome は SVG 内に配置された画像をキャッシュしないことを発見しましたno-cache。Firefox と IE10 はこの設定を無視しているようです。

静的 SVG を使用して小さなテスト ページを作成しました。

HTML:

<div style="width: 500px; text-align: center;">
    <input id="move-left-btn" type="button" value="&lt;&lt;">
    <input id="move-right-btn" type="button" value="&gt;&gt;">
</div>

<div class="svgwrapper" style="width: 500px; height: 250px; background-color: lightgrey;">
    <svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" width="500" height="250">
        <g id="svggroup" class="transition-on" transform="matrix(0.2,0,0,0.2,80,35)">
            <image width="1672" height="887" opacity="1" xlink:href="https://dl.dropboxusercontent.com/sh/q7htlj5h8qqfhjf/SVDuynM7R3/car.png"></image>
        </g>
    </svg>
</div>

Javascript:

$(document).ready(function() {
    var curXPos = 80;

    // Local test function which represent some server calls in my "real life" scenario
    // Just updates the x-position in the transform matrix in this test case
    function updateSvgText(svgText, posXDelta) {
        curXPos += posXDelta;
        if (curXPos < 0) {
            curXPos = 160;
        } else if (curXPos > 160) {
            curXPos = 0;
        }

        return svgText.replace(/matrix\(.*\)/, 'matrix(0.2,0,0,0.2,' + curXPos + ',35)');
    }

    // Fetch the new SVG (in real life from server) and rerender it
    function moveSvg(posXDelta) {
        var svg = $('#svg'),
            svgText = updateSvgText($('.svgwrapper').html(), posXDelta);

        svg.empty();
        svg.append($(svgText).children());
    }

    $('#move-left-btn').click($.proxy(moveSvg, this, -20));
    $('#move-right-btn').click($.proxy(moveSvg, this, 20));
});
  • cache-controlソース画像のヘッダーが設定された作業例no-cache(「移動」ボタンを押すたびにクロムでちらつきます):
    http://jsfiddle.net/zF6NF/4/

  • cache-controlヘッダーがmax-age=315360000,public(ちらつきなし)に設定された別のソース画像の同じ例:
    http://jsfiddle.net/zF6NF/5/

Chrome では、最初の例でボタンをクリックするたびに画像がリロードされるのを確認できます (画像の「ちらつき」と開発ツールのネットワーク タブに表示されます) が、Firefox では両方の例でリロードなしで SVG がスムーズに再レンダリングされます。

いくつかの追加情報:

  1. これはほんの一例です。私の「実生活のシナリオ」では、(updateSvgTextメソッド呼び出しの代わりに) サーバーから新しい SVG を受け取ります。つまり、変換マトリックス属性の値を変更して SVG の部分的な更新を実行することはできませんが、毎回 SVG 全体を再レンダリングします (少なくとも今では...)。

  2. 画像がどこから来たのかを制御できません。これは、2 つのことを意味します。

    • cache-controlヘッダーを変更できません
    • Base64 でエンコードされたデータ URI を作成できず、それらをローカルに保存し、レンダリングする前に SVG 内の画像をそれらのデータ URI に置き換えるだけです (「同じリソース オリジン」ポリシーのため、Base64 でエンコードされたデータ URI を作成できません... )

どちらかの方法はありますか...

  • cache-controlイメージが制御されていないリモートの場所からのものであっても、ヘッダーをローカルで上書き/上書きしますか?
  • 別のドメインからロードされたイメージから Base64 でエンコードされたデータ URI を作成します。クライアント側を制御できませんか?
  • どうにかして Chrome に SVG 内の画像を常にキャッシュするように指示しますか?

言うまでもなく、他のソリューションも大歓迎です!

ありがとう

4

1 に答える 1

3

残念ながら、キャッシングに関しては、99% サーバーの仕事です。

詳細ガイド:こちら

ブラウザーは、特定の条件に基づいて常にファイルの最新バージョンを探します。

  • キャッシュされたエントリに有効期限がなく、コンテンツがブラウザ セッションで初めてアクセスされている
  • キャッシュされたエントリには有効期限がありますが、有効期限が切れています
  • Cache-Control/Pragma はブラウザにキャッシュしないように指示します
  • ヘッダーの Etag は面倒です。

ソリューションに関しては、次のとおりです。

  • キャッシュが必要であることをサーバー担当者に強く主張してください (etag を削除し、Cache-Control: public,max-age=31536000、Pragma: public を削除します)。
  • サイトからの画像を必要とするドメインにプロキシを作成し (オプションで base64 に変換)、クライアントに送信します (適切なヘッダーを使用)。PHP の例を次に示します
于 2013-12-21T01:02:14.840 に答える