System.Net.Http.HttpClient 返回错误“ERR:缺少 UA30”

System.Net.Http.HttpClient returns error "ERR: Missing UA30"

提问人:kumkee 提问时间:10/29/2023 最后编辑:kumkee 更新时间:10/31/2023 访问量:93

问:

下面的代码在响应内容中给了我一个相当奇怪的错误。我在 Internet 上的任何地方都找不到错误。它只发生在某些特定的网站上。 此存储库上还有另一个版本的代码同时测试服务器 URL。 由于 F# 和 C# 共享相同的框架,我怀疑这也会发生在 C# 上,但我还没有测试它,因为我的 C# 不那么流畅。ERR: Missing UA30ics

open System.Net.Http

let url = "https://portal.macleans.school.nz/index.php/ics/school.ics"
(* other working urls:
    "https://gist.githubusercontent.com/DeMarko/6142417/raw/1cd301a5917141524b712f92c2e955e86a1add19/sample.ics"
    "https://www.kayaposoft.com/enrico/ics/v2.0?country=gbr&fromDate=01-01-2023&toDate=31-12-2023&region=eng"
    "https://www.phpclasses.org/browse/download/1/file/63438/name/example.ics"
    *)


let getAsync (client: HttpClient) (url: string) =
    async {
        let! content = client.GetStringAsync url |> Async.AwaitTask
        let len = content.Length
        printf "%d" len

        match len with
        | len when len < 50 -> printfn " content: %s" content
        | _ -> printfn ""
    }

let client = new HttpClient()

getAsync client url
|> Async.RunSynchronously

我尝试过的所有方法都记录在上面提到的 GitHub 存储库中。

我预计不会出现错误,因为命令能够毫无问题地下载文件 -curlics

curl https://portal.macleans.school.nz/index.php/ics/school.ics -o output.ics
C .NET F# HttpClient iCalendar

评论

0赞 Foole 10/29/2023
该消息出现在哪里?作为响应的内容还是作为例外?如果是后者,请添加堆栈跟踪。
0赞 kumkee 10/29/2023
@Fooe 在响应的内容中。
1赞 Foole 10/29/2023
该错误很可能来自服务器,并且任何 http 客户端都会发生。或者,它可能来自您和服务器之间的代理。
0赞 kumkee 10/29/2023
@Foole curl 或 Chrome 不会出现任何错误
1赞 kumkee 10/29/2023
@Foole你是对的。事实证明,服务器会拒绝任何没有 User-Agnet 值的请求。问题解决了。非常感谢。

答:

0赞 ala mehrabi 10/29/2023 #1

您可以尝试在 HTTP 请求中设置用户代理设置标头。 例如:

open System.Net.Http

let url = "https://portal.macleans.school.nz/index.php/ics/school.ics"

let getAsync (client: HttpClient) (url: string) =
    async {
        let request = new HttpRequestMessage(HttpMethod.Get, url)
        request.Headers.Add("User-Agent", "NonEmptyUA")

        let! response = client.SendAsync(request) |> Async.AwaitTask
        let content = response.Content.ReadAsStringAsync() |> Async.AwaitTask
        printfn "Response content length: %d" (content.Length)

        if content.Length < 50 then
            printfn "Response content: %s" content
    }

let client = new HttpClient()

getAsync client url
|> Async.RunSynchronously