HttpWebRequest request = WebRequest.CreateHttp(domain);
request.Method = "GET";
request.AllowAutoRedirect = true;
为什么重定向到 301/302 有效,但 308 无效?
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
语句中使用它,或者如果用作单例则正确管理其生命周期。