C# - HttpWebRequest 在 308 状态代码上没有自动重定向

问题描述 投票:0回答:1
我正在尝试向域发出请求,并且在重定向链(301,302 状态代码)中,有一个 308 重定向不是自动重定向,而是抛出带有消息“无效状态代码 308”的 WebExpections。我下面只有简单的 WebRequest。

HttpWebRequest request = WebRequest.CreateHttp(domain); request.Method = "GET"; request.AllowAutoRedirect = true;
为什么重定向到 301/302 有效,但 308 无效?

c# redirect httprequest
1个回答
0
投票
您遇到的

HttpWebRequest

 不自动处理用于重定向的 HTTP 308 状态代码的行为可能是由于 
308 Permanent Redirect
 状态代码与 
301 Moved Permanently
302 Found
 状态代码相比相对较新。 
HttpWebRequest
 类是在 
308
 状态代码标准化之前实现的(RFC 7538,于 2015 年发布)。

截至 2023 年知识截止,

HttpWebRequest

 被视为遗留类,Microsoft 建议使用 
HttpClient
 进行新开发。 
HttpClient
 类更加现代,可以无缝处理包括 
308 Permanent Redirect
 在内的重定向。

如果您无法切换到

HttpClient

 并且需要解决 
HttpWebRequest
 类的行为,您可以捕获 
WebException
 并通过从响应中读取 
308
 标头并创建一个对指定 URL 的新请求。
这是一个简化的示例:

Location

请记住,如果未实现循环检测和允许的最大重定向数量,手动重定向处理可能会导致无限循环。
上面的示例并没有处理所有细节,例如将标头从原始请求复制到新请求(除了由 

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(domain); request.Method = "GET"; request.AllowAutoRedirect = true; try { using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { // Process the response... } } catch (WebException ex) { if (ex.Response is HttpWebResponse response) { // Check if the status code is 308 if (response.StatusCode == (HttpStatusCode)308) { // Read the "Location" header from the response string newLocation = response.Headers["Location"]; if (!string.IsNullOrEmpty(newLocation)) { // Create a new request to the new location request = (HttpWebRequest)WebRequest.Create(newLocation); request.Method = "GET"; // Optionally, copy any necessary properties from the original request // ... using (HttpWebResponse newResponse = (HttpWebResponse)request.GetResponse()) { // Process the response from the new location... } } } } }

自动管理的标头),但应该为您提供一个起点。另外,请记住妥善处理和处置您的

HttpWebRequest

,以防止资源泄漏。
最终,如果您能够使用
WebResponses

,那将是最强大且面向未来的选择:

HttpClient

HttpClient client = new HttpClient();
// HttpClient handles redirections including 308 by default.
HttpResponseMessage response = await client.GetAsync(domain);

if (response.IsSuccessStatusCode)
{
    // Process the response...
}
还实现了

HttpClient

,因此在 
IDisposable
 语句中使用它,或者如果用作单例则正确管理其生命周期。

© www.soinside.com 2019 - 2024. All rights reserved.