Https GET 请求在 Postman 和浏览器中通过但在代码中失败
Https GET request passes in Postman and browser but fails in code
我正在尝试通过休息 API 获得 JSON,目标是 .Net 4.5
我在代码中尝试了各种方法,但最终都得到了:
"Authentication failed because the remote party has closed the
transportstream" .
完全相同的 URL 通过浏览器和 Postman 工作。
到目前为止,我已经尝试使用 .Net 的 WebClient、HttpClient 和 HttpWebRequest,结果相同。我已经尝试比较 Postman 和我的代码之间的请求(通过 RequestBin),但即使它们相同,我仍然不断返回:
Authentication failed because the remote party has closed the
transport
我当前的代码使用的是 HttpWebRequest,但每个解决方案都可以。
我试过所有的安全协议,其中一些会导致 API 到 return 404
而有些会导致服务器 return
"Authentication failed because the remote party has closed the
transport stream".
这是我当前的代码:
public string GetCityStreets()
{
var url = "https://data.gov.il/api/action/datastore_search?resource_id=a7296d1a-f8c9-4b70-96c2-6ebb4352f8e3&q=26";
var request = (HttpWebRequest)WebRequest.Create(url);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls;
var response = (HttpWebResponse)request.GetResponse();
string jsonResponse;
using (var reader = new StreamReader(response.GetResponseStream()))
{
jsonResponse = reader.ReadToEnd();
}
return jsonResponse;
}
在我现在的代码中,实际发出请求时抛出异常:request.GetResponse()
.
本质上,我需要的是从 API.
中获取 JSON
服务器端似乎正在检查用户代理(大概是为了阻止机器人程序和其他代码(如您的!)访问端点)。要绕过此问题,您需要将用户代理设置为一个值,使其认为您是网络浏览器。
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36";
举个例子。
您不妨考虑将 ServicePointManager.SecurityProtocol
设置为一次(在应用程序启动时),而不是在每次请求时设置。
这可以使用 HttpClient(.net 4.5 及更高版本)
var url = "https://data.gov.il/api/action/datastore_search?resource_id=a7296d1a-f8c9-4b70-96c2-6ebb4352f8e3&q=26";
var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "C# App");
Task<string> response = client.GetStringAsync(url);
Console.WriteLine(response.Result);
认为服务器需要用户代理。
设置SecurityProtocolType.Tls12
在初始化请求之前:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12`
var request = WebRequest.CreateHttp(url);
如果您在 Windows 7。在 Windows 10,您应该只需要 SecurityProtocolType.SystemDefault
。
注意:启用TLS1.3
(在Windows 7 和Windows 10), 如果你不使用 .Net 4.8
或 .Net Core 3.0
,因为它没有枚举器,你可以设置它:
var secProtoTls13 = (SecurityProtocolType)12288;
删除您在那里设置的所有其他 SecurityProtocolType
。
设置 User-Agent
header 也是强制性的,否则您将收到 404
(未找到)。这是 FireFox header:
request.UserAgent = "Mozilla/5.0 (Windows NT 10; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0";
关于 User-Agent header 的注释:此特定站点未激活 HTTP Strict Transport Security (HSTS)。但是有些网站会这样做,当他们看到 WebBrowser 支持它时。 HttpWebRequest
不理解,所以它只会等待一个永远不会到来的响应,因为站点正在等待 interaction.
您可能想改用 IE11
header。
另外添加这个 header:
request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");
我正在尝试通过休息 API 获得 JSON,目标是 .Net 4.5
我在代码中尝试了各种方法,但最终都得到了:
"Authentication failed because the remote party has closed the transportstream" .
完全相同的 URL 通过浏览器和 Postman 工作。
到目前为止,我已经尝试使用 .Net 的 WebClient、HttpClient 和 HttpWebRequest,结果相同。我已经尝试比较 Postman 和我的代码之间的请求(通过 RequestBin),但即使它们相同,我仍然不断返回:
Authentication failed because the remote party has closed the transport
我当前的代码使用的是 HttpWebRequest,但每个解决方案都可以。
我试过所有的安全协议,其中一些会导致 API 到 return 404
而有些会导致服务器 return
"Authentication failed because the remote party has closed the transport stream".
这是我当前的代码:
public string GetCityStreets()
{
var url = "https://data.gov.il/api/action/datastore_search?resource_id=a7296d1a-f8c9-4b70-96c2-6ebb4352f8e3&q=26";
var request = (HttpWebRequest)WebRequest.Create(url);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls;
var response = (HttpWebResponse)request.GetResponse();
string jsonResponse;
using (var reader = new StreamReader(response.GetResponseStream()))
{
jsonResponse = reader.ReadToEnd();
}
return jsonResponse;
}
在我现在的代码中,实际发出请求时抛出异常:request.GetResponse()
.
本质上,我需要的是从 API.
服务器端似乎正在检查用户代理(大概是为了阻止机器人程序和其他代码(如您的!)访问端点)。要绕过此问题,您需要将用户代理设置为一个值,使其认为您是网络浏览器。
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36";
举个例子。
您不妨考虑将 ServicePointManager.SecurityProtocol
设置为一次(在应用程序启动时),而不是在每次请求时设置。
这可以使用 HttpClient(.net 4.5 及更高版本)
var url = "https://data.gov.il/api/action/datastore_search?resource_id=a7296d1a-f8c9-4b70-96c2-6ebb4352f8e3&q=26";
var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "C# App");
Task<string> response = client.GetStringAsync(url);
Console.WriteLine(response.Result);
认为服务器需要用户代理。
设置SecurityProtocolType.Tls12
在初始化请求之前:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12`
var request = WebRequest.CreateHttp(url);
如果您在 Windows 7。在 Windows 10,您应该只需要 SecurityProtocolType.SystemDefault
。
注意:启用TLS1.3
(在Windows 7 和Windows 10), 如果你不使用 .Net 4.8
或 .Net Core 3.0
,因为它没有枚举器,你可以设置它:
var secProtoTls13 = (SecurityProtocolType)12288;
删除您在那里设置的所有其他 SecurityProtocolType
。
设置 User-Agent
header 也是强制性的,否则您将收到 404
(未找到)。这是 FireFox header:
request.UserAgent = "Mozilla/5.0 (Windows NT 10; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0";
关于 User-Agent header 的注释:此特定站点未激活 HTTP Strict Transport Security (HSTS)。但是有些网站会这样做,当他们看到 WebBrowser 支持它时。 HttpWebRequest
不理解,所以它只会等待一个永远不会到来的响应,因为站点正在等待 interaction.
您可能想改用 IE11
header。
另外添加这个 header:
request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");