cefsharp - 如何绕过 CefSharp 和 libcef 手动处理 POST 请求?
问题描述
我是“网络编程”的新手,我想知道是否可以在 CEFSharp 中手动处理 POST 请求和响应。场景是我正在使用 CEFSharp 与之交互的网站正在创建请求,但如果可能的话,我想在那之后进行控制。我想象 ResourceRequestHandler 必须是类似以下的东西,必须以某种方式将 CEFSharp IRequest 转换为 .NET HttpRequestMessage:
public class CustomResourceRequestHandler : CefSharp.Handler.ResourceRequestHandler
{
private static readonly HttpClient hc = new();
private readonly AutoResetEvent are;
public CustomResourceRequestHandler(AutoResetEvent are)
{
this.are = are;
}
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
{
var hrm = new HttpRequestMessage(HttpMethod.Post, request.Url);
//How to add Headers properly?
foreach (string rh in request.Headers)
hrm.Headers.Add(rh, request.Headers[rh]);
//How to add content properly?
Task.Factory.StartNew(async() =>
{
are.WaitOne();
var response = hc.SendAsync(hrm);
await response;
// Do Something with response.Result
});
return CefReturnValue.Cancel;
}
}
问题是:首先,这可能吗?由于底层套接字已更改,网络服务器不会抱怨吗?二、如何正确复制IRequest到HttpRequestMessage?我添加了标题,不知道是否正确完成,但我正在努力转换内容字段。第三,复制标题和内容是否足够?
解决方案
在修改了 CEFSharp 和 .NET HttpRequest 之后,这是一个半工作示例。我必须复制 Cookie、标题和内容才能使其正常工作。调用 are.Set() 将触发手动请求和读取响应。在进行此类操作之前,请检查@amailand 有问题的评论,这可能会为您提供更好的方法。
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
{
Task.Factory.StartNew(async() =>
{
//Cookies
var cm = chromiumWebBrowser.GetCookieManager();
var t = cm.VisitUrlCookiesAsync(request.ReferrerUrl, true);
Task.WaitAll(t);
var cookies = t.Result;
var cc = new CookieContainer();
using HttpClientHandler hch = new()
{
CookieContainer = cc,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
using HttpClient hc = new(hch);
foreach (var cookie in cookies)
cc.Add(new System.Net.Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));
var hrm = new HttpRequestMessage(HttpMethod.Post, request.Url);
//Headers
foreach (string rh in request.Headers)
hrm.Headers.TryAddWithoutValidation(rh, request.Headers[rh]);
//Check if more headers should be added manually
//Content
hrm.Content = new StringContent(Encoding.UTF8.GetString(request.PostData.Elements[0].Bytes),
Encoding.UTF8, "application/json");
are.WaitOne();
var response = hc.SendAsync(hrm);
await response;
if (response.Result.StatusCode != HttpStatusCode.OK) return;
var t1 = response.Result.Content.ReadAsByteArrayAsync();
Task.WaitAll(t1);
// result is in t1.Result
});
return CefReturnValue.Cancel;
}
推荐阅读
- java - 我的 createFragment 方法应该如何返回我的片段?
- c# - “.... 是一个变量,但用作类型”在 switch 语句中
- javascript - 使用正则表达式在两个没有空格的空间字符之间获取一些字符
- angular - 以角度更新html formArray中的值
- intellij-idea - Intelij IDEA - UML 插件 - 生成的图表改变颜色
- twitter - 有什么方法可以在不再次申请 Twitter Dev 的情况下以其他人的身份发送推文?
- swift - UIKit中具有可调模糊半径的模糊视图
- azure-sql-database - 如何使用 ADF 创建月度文件?
- php - 如何使搜索过滤器与 Yii2 中的格式化日期一起使用?
- python - 定义了 __all__ 的包的 Sphinx 文档(使用 automodapi 扩展)