c# - 使用 C# HttpClient 下载的 Skype Emoticon 与使用浏览器下载的字节流不同
问题描述
这是最离奇的事情。
我正在尝试使用 C# HttpClient 下载此文件: https ://statics.teams.microsoft.com/evergreen-assets/skype/v2/smile/50.png
它恰好是 Microsoft Teams 表情图像文件之一。
(顺便说一句,我必须使用 Chrome 将这张图片本地下载到我的机器上,然后从那里上传,因为 StackOverflow 图片上传也无法处理 URL……)
我已经尝试了许多不同的破解代码来下载这个文件 - 最直接和最常用的方法是:
var client = new HttpClient();
var webStream = await client.GetStreamAsync("https://statics.teams.microsoft.com/evergreen-assets/skype/v2/smile/50.png");
using (var fileStream = new FileStream("smilely.png", FileMode.OpenOrCreate)) {
webStream.CopyTo(fileStream);
}
我尝试了几种使用 HttpClient、System.Net.WebClient 和原始 WebRequest 的不同方法,结果相同。
如果我将 URL 放入我的浏览器并转到它,我会按预期看到图像,但如果我从 C# 下载文件,我会得到一个无法打开的损坏图像。
使用浏览器下载的正确文件为 2127 字节,从正确的 PNG 标头字节开始,如下所示:
89 50 4E 47 0D 0A 1A 0A
我以编程方式下载的文件被搞砸了,具有完全不同的字节流,只有 2093 个字节,并且开始:
1F 8B 08 00 00 00 00 00
我从同一组下载其他表情图像没有这个问题,例如https://statics.teams.microsoft.com/evergreen-assets/skype/v2/laugh/50.png
这到底是怎么回事?
解决方案
1F 8B
是 GZIP 的神奇数字。
如果我们查看响应内容标头:
var client = new HttpClient();
var response = await client.GetAsync("https://statics.teams.microsoft.com/evergreen-assets/skype/v2/smile/50.png");
var contentHeaders = response.Content.Headers;
我们可以看到ContentEncoding
是gzip
。
所以看起来服务器配置出了点问题。通常,如果您明确声明您接受带有标头的编码响应,服务器只会为您提供内容编码的内容Accept-Encoding
,但看起来这个特定的服务器没有按照该文件的规则播放。
您的浏览器确实说它接受了 gzip 编码的文件,因此当它收到 gzip 编码的响应时不会闪烁。您的 C# 代码没想到会这样。
您可以使用HttpClient
以下命令自动解压缩 gzip 编码的内容:
var handler = new HttpClientHandler()
{
AutomaticDecompression = System.Net.DecompressionMethods.GZip
};
var client = new HttpClient(handler);
推荐阅读
- c# - C# NetTopology CoordinateValue 无限循环
- java - 在 Hibernate 中使用更新但仍在创建表
- ruby-on-rails - 迁移到 pg 后 Gitlab-ci.yml rspec 测试错误
- javascript - 自动滚动到 iframe 的底部
- flutter - 颤振 SelectableLinkify - 链接不起作用
- c++ - C ++ cUrl通过api向电报机器人发送图像buff
- reactjs - Antd的表格行编辑模式下改变输入字段的数字格式?
- swift - 在 NSImage 右侧绘制文本 - 不需要的间距
- html - 角度复选框的默认状态是什么?
- python - 如何在 Python 中自定义周数?