0

我正在使用RangeFilePathResult该类从 MVC 控制器提供 mp3 文件。

动作定义如下:

[CacheFilter]
[OutputCache(CacheProfile = "Mp3Cache")]
public RangeFilePathResult Mp3Completed(string f)
{
    FileInfo info = new FileInfo(string.Format("C:\\test\\{0}.mp3", f));
    return new RangeFilePathResult("audio/mpeg", info.FullName, info.LastWriteTimeUtc, info.Length);
}

并且缓存策略如下:

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="Mp3Cache" duration="3600" varyByParam="f" location="Any" />
    </outputCacheProfiles>
  </outputCacheSettings>
</caching> 

为什么这可以正常工作?似乎您需要明确varyByHeader确保范围请求与输出缓存一起使用?我要解决的问题是 iOS 上的 jPlayer 将无法显示 MP3 文件的持续时间,并且在使用传统 FilePathResult 服务时会呈现 NaN - 它在此实现下工作。

4

1 回答 1

1

这里最重要的是对范围请求的响应不是典型的200 OK而是206 Partial Content

如果是206 Partial Content ,则必须满足几个附加条件:

  • 请求必须包含一个Range标头字段,指示所需范围,并且可能包含一个If-Range标头字段以使请求有条件
  • 响应必须包含一个Content-Range标头字段,指示包含在此响应中的范围,或者包含每个部分的multipart/byteranges Content-Type包含Content-Range字段。
  • 响应必须包含ETag和/或Content-Location(如果标头将在对同一请求的 200 响应中发送)
  • 响应必须包括Date

现在每个支持 HTTP 协议的缓存机制(如果location="Any"是浏览器、代理服务器和您的托管 IIS)都必须知道206 Partial Content不同于200 OK并相应地处理它。您可以在下面找到缓存206 Partial Content响应的最重要规则:

  • ETag如果或Last-Modified标头不完全匹配,则缓存不得将 206 响应与其他先前缓存的内容组合
  • 不支持RangeandContent-Range标头的缓存不能缓存 206 响应

总结一下,您不需要使用varyByHeader,因为每个遵循 HTTP 协议的缓存都知道,在206 Partial Content的情况下,RangeContent-Range标头是变体的一部分。

于 2012-09-12T20:22:07.960 回答