【问题标题】:WebHttpRequest fails (500) while postman successfully runs the web GET request当邮递员成功运行 Web GET 请求时,WebHttpRequest 失败 (500)
【发布时间】:2018-08-10 01:46:41
【问题描述】:

我尝试从特定站点获取特定值...

网站使用 Ajax 调用定期更新值 https://www.plus500.co.il/api/LiveData/FeedUpdate?instrumentId=19

(您可以导航到该地址并查看是否收到 XML 响应。)

使用邮递员: 发送

GET /api/LiveData/FeedUpdate?instrumentId=19 HTTP/1.1
Host: www.plus500.co.il
Cache-Control: no-cache
Postman-Token: f823c87d-3edc-68ce-e1e7-02a8fc68be7a

我得到一个有效的 Json 响应...

不过,当我从 C# 中尝试时:

var webRequest = WebRequest.CreateHttp(@"https://www.plus500.co.il/api/LiveData/FeedUpdate?instrumentId=19");
webRequest.Method = "GET";
using (var response = webRequest.GetResponse())
{...}

请求失败,错误代码 403(禁止)

添加时:

webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36";

请求失败,错误代码为 500(内部服务器错误)

添加(编辑)

我也开始了

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 |
                                   SecurityProtocolType.Tls11 |
                                   SecurityProtocolType.Tls |
                                   SecurityProtocolType.Ssl3;

另外,我尝试设置一个 CookieContainer,但结果是相同的 500。

为什么 Postman/Chrome 成功地查询了这个 API 而 C# Webrequest 却没有?
有什么区别?

【问题讨论】:

  • 您需要显式设置ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 不需要验证回调。此外,您应该提供一个 CookieContainer(它将设置 2 个 cookie)。如果需要示例代码,请告诉我。
  • @Jimi 我确实设置了一个 cookie 容器,但它是一样的。忘记显示我启用了所有 Tls1、Tls2、Ssl。
  • 这里还有什么没有显示的吗?这个连接需要什么(通过排除测试):Tls1.2,一个用户代理头,自动解压(.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;)加上一个Accept-encoding头。 CookieContainer 可能有用(在您这边),但不是必需的。服务器证书验证回调也不是(提供了连接地址,可能需要不同的访问级别)。你没有说中间是否有代理。
  • 接受编码标头:webRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8");

标签: c# ajax web-services httpwebrequest postman


【解决方案1】:

因此,失败的原因是默认情况下,邮件头包含在来自邮递员的客户端请求中,尽管不是来自 C# 请求。

使用像 Fiddler (https://www.telerik.com/fiddler) 这样的程序,您可以查看请求以查看邮递员请求的标头是:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8    
Accept-Encoding: gzip, deflate, br    
Accept-Language: en-US,en;q=0.9    
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36

然而来自 C# 只是

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

像这样填写额外的客户端请求标头可以让它顺利通过:

webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
webRequest.Headers.Add("Accept-Encoding", "gzip deflate,br");
webRequest.Headers.Add("Accept-Language", "en-US,en;q=0.9");

【讨论】:

  • 看起来所需的标题是 User-Agent 以避免 403 和 Accept-Encoding 以避免 500。
  • 这似乎工作......我只需要计算返回流。谢谢
  • 谢谢,现在很好用。不知道邮递员会添加它不显示的标题。再次感谢
猜你喜欢
  • 2020-08-28
  • 2020-03-07
  • 2020-07-23
  • 1970-01-01
  • 2020-05-22
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
相关资源
最近更新 更多