为什么每个 IIS 响应的末尾(作为最后一个字节)可能有一个 UTF-8 BOM?

Why might there be a UTF-8 BOM at the end (as the last bytes) of each IIS response?

在通过 IIS 管道运行并发出带有字符集的内容类型(根据 <globalization> 元素)的每个页面的末尾,UTF-8 BOM 被 添加到响应结束。这是无效的并且破坏了 UpdatePanel 的使用。

如果添加了BOM,应该是第一个字符..

curl | xxd 将最后三个字节显示为 EF BB BF,或 UTF-8 BOM。

0002b830: 2f62 6f64 793e 0d0a 3c2f 6874 6d6c 3eef  /body>..</html>.
0002b840: bbbf                                     ..

备注:

所有未随 IIS 或 ASP.NET MVC 一起提供的 IIS 模块已被删除,问题仍然存在。

可能是什么问题,故障排除的后续步骤是什么?

这个问题完全是 ASP.NET 管道相关的,因为一些很棒的“处理程序”被添加到 MVC 管道(通过 Global.asax 中注册的过滤器)和 WebForms(通过添加一个基页..);两种形式最终都将 HttpContext.Response.Filter 重新分配给了一个特殊的代表 .. 或者在这种情况下,多个包装的代表。

这些“处理程序”有效地导致写入一个流的内容,然后是来自另一个“处理程序”的 empty-except-for-BOM 响应,效果类似于:

 _stream.Write(someOutputBuffer, ..);
 _stream.Write(originalBuffer, ..);

因此,如果 originalBuffer 碰巧是空的,除 BOM 外,输出将在“末尾”附加 BOM,而不是中间某处的同样无效的位置响应..

切换到 UTF-8 响应编码导致了该行为,因为这些“处理程序”中的每一个都使用当前响应编码打开了一个流,该编码已切换到 UTF-8,并且默认的 UTF-8 编码将发出默认为 BOM。

修复是 create the UTF-8 encoding used in a way that specifies not to emit the BOM by default,而不是直接使用 Response.ContentEncoding(带 BOM 的 UTF-8)。 (代码完全可疑,尽管那是另一天的任务..)

tldr; 简陋的“处理程序”并不总是安装为 IIS modules/handlers。