首页 > 解决方案 > 如何绕过 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?我添加了标题,不知道是否正确完成,但我正在努力转换内容字段。第三,复制标题和内容是否足够?

标签: cefsharpchromium-embedded

解决方案


在修改了 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;
    }

推荐阅读