【问题标题】:Response.Filter breaks encoding randomlyResponse.Filter 随机中断编码
【发布时间】:2012-10-31 13:25:01
【问题描述】:

我有一个使用 WCF 的简单 html 和 javascript 客户端应用程序(不是 asp.net 应用程序)。我需要更改静态页面中的一些变量,所以我认为 Response.Filter 是最适合我的选项。我写了几行代码,它工作了,但是在我在浏览器上刷新了几次之后,我注意到有一个错误。某些东西破坏了页面的编码。我做错了什么?

Global.asax:(我也尝试了其他事件,但没有任何变化)

private void Application_PostReleaseRequestState(object sender, System.EventArgs e)
{
    if (Request.CurrentExecutionFilePathExtension.EndsWith(".html") || Request.CurrentExecutionFilePathExtension.EndsWith(".js"))
    {
        Response.Filter = new ContentFilter(Response.Filter);
    }
}

内容过滤器.cs

public class ContentFilter : MemoryStream
{
    private Stream outputStream = null;

    private Regex version = new Regex("%version%", RegexOptions.Compiled | RegexOptions.Multiline);


    public ContentFilter(Stream output)
    {
        outputStream = output;
    }


    public override void Write(byte[] buffer, int offset, int count)
    {
        // Convert the content in buffer to a string
        string contentInBuffer = UTF8Encoding.UTF8.GetString(buffer);

        contentInBuffer = version.Replace(contentInBuffer, "2");

        outputStream.Write(UTF8Encoding.UTF8.GetBytes(contentInBuffer), offset, UTF8Encoding.UTF8.GetByteCount(contentInBuffer));
    }
}

注意:我在 Windows 8 上使用 IIS 7.5。

当我在 Write 方法中调试 ContentFilter.cs 作为 contentInBuffer 变量的值时,我看到了这些。我在 IIS 设置中默认有 GZIP 压缩,也许就是这样。

`�\b\0\0\0\0\0\0�Z�n�����w3\b(�\"�VD�I���8A�a���r �����,m�\t��>@�����t�\n(P�/��+��]���$���B�3s�|���_不...

【问题讨论】:

  • 您在 Fiddler 中检查过您的响应内容吗?我见过几个与 Response.Filter 相关的问题,但它们大多与错误地更新内容有关。我首先验证标题和内容字节。您在回复中使用国际字符吗?
  • 是的,有土耳其字符,如 ö、ç、ü、ş 和 ğ。我会用提琴手检查它。我不明白为什么,但第一次打开页面,刷新 3 次后它开始失败。
  • � 这是我的提琴手的输出。 :)

标签: c# .net iis filtering httpresponse


【解决方案1】:

您忽略了传递给您的Write 实现的offset 和count。使用同样采用索引和计数的 GetString 覆盖可能会有所帮助。

不过,恐怕还有其他一些问题。您在Write 函数中收到的数据将分块到达。如果第一个块以“%vers”结尾,而第二个块以“ion%”开头,会发生什么?

此外,由于非 ASCII 字符在 UTF-8 中表示为多个字节,因此单个 Unicode 字符可能会“散布”到对 Write 的两个后续调用中,这将导致 UTF8Encoding.UTF8.GetString 失败。

【讨论】:

  • 我尝试禁用 IIS 压缩,现在效果很好,但不是解决方案。您对偏移量和计数是正确的。我只是想让它先工作。我需要这个,因为缓存的 javascript 和 css 文件会导致一些问题。由于我的客户端应用程序不是 ASP.NET 应用程序,我需要一些东西来使用户的浏览器缓存无效。您有更好的想法来实现这一目标吗?
  • @Amount 是正确的 - 由于您的响应中包含非 ASCII 字符,因此您必须先缓冲数据,然后才能对其进行更改。
【解决方案2】:

我也遇到了这个问题,这是由于 IIS 中静态内容的 GZip 压缩。为了防止损坏,我通过以下 Web.Config 条目禁用了静态压缩:

<system.webServer>
  <urlCompression doStaticCompression="false" />
</system.webServer>

事实证明,小于 2700 字节的文件默认不会被压缩(请参阅 IIS 压缩设置),因此您只会看到大于该值的静态内容。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 2022-12-07
    • 2021-03-25
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多