如何用VB/C#正确下载iCloud服务器上的iCalendar文件?
解决iCloud日历ICS文件下载得到二进制文件的问题
我来帮你搞定这个问题!你遇到的情况是因为iCloud服务器返回的是gzip压缩后的内容——浏览器会自动识别并解压这些压缩数据,但你的WebClient代码默认没有开启自动解压功能,所以保存下来的是未解压的二进制压缩文件,而不是正常的ICS文本。
下面给你两种可行的解决方案,优先推荐第二种更现代的方法:
方法1:自定义WebClient支持自动解压
你可以继承WebClient类,重写GetWebRequest方法来启用自动解压功能,这样就能像浏览器一样处理压缩响应了:
Imports System.Net Public Class GzipWebClient Inherits WebClient Protected Overrides Function GetWebRequest(address As Uri) As WebRequest Dim request As HttpWebRequest = MyBase.GetWebRequest(address) ' 启用Gzip和Deflate两种解压方式 request.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate Return request End Function End Class
然后使用这个自定义的GzipWebClient来下载,同时注意修正请求头(原来的Content-Type是多余的,应该用Accept告诉服务器我们接受的内容类型):
Using wb As New GzipWebClient() wb.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.33 Safari/537.36") wb.Headers.Add("Accept", "text/calendar, text/*") wb.DownloadFile("https://p10-calendars.icloud.com/holiday/CN_zh.ics", "C:\Users\Johnson\Desktop\1.ics") End Using
方法2:使用HttpClient(推荐,WebClient已过时)
在.NET Core/.NET 5+版本中,WebClient已经被标记为过时,推荐使用更强大的HttpClient。HttpClient默认支持自动解压,我们可以显式配置确认:
Imports System.Net.Http Imports System.IO Async Sub DownloadIcsFile() Dim handler As New HttpClientHandler() handler.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate Using client As New HttpClient(handler) client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.33 Safari/537.36") client.DefaultRequestHeaders.Accept.ParseAdd("text/calendar, text/*") ' 发送请求并确保响应成功 Dim response As HttpResponseMessage = Await client.GetAsync("https://p10-calendars.icloud.com/holiday/CN_zh.ics") response.EnsureSuccessStatusCode() ' 读取文本内容并保存到文件 Dim icsContent As String = Await response.Content.ReadAsStringAsync() Await File.WriteAllTextAsync("C:\Users\Johnson\Desktop\1.ics", icsContent) End Using End Sub
关键说明
- 服务器返回压缩内容是为了减少传输体积,浏览器会自动处理
Content-Encoding: gzip响应头并解压,我们的客户端代码需要显式开启这个功能。 - 去掉了多余的
Content-Type头:这个头是用来告诉服务器我们发送的请求体类型,而下载是GET请求,不需要设置;改用Accept头告诉服务器我们希望接收的内容类型,更符合HTTP规范。
内容的提问来源于stack exchange,提问作者Johnson
相关产品推荐
相关产品推荐

