如何绕过CefSharp与libcef手动处理POST请求 相关实现问题咨询
问题解答
1. 方案可行性说明
你的方案是完全可行的,底层Socket变化不会导致服务端报错。服务端只会校验请求报文本身的合法性(包括头、内容、签名、Cookie等),感知不到客户端底层Socket的差异。
需要注意的唯一一个前置要求:你需要在OnBeforeResourceLoad的同步执行阶段就把IRequest的所有属性全部读取完毕,CEF的IRequest对象会在该方法返回后被回收,不能放到异步Task中再访问,否则会出现空引用异常。
你返回CefReturnValue.Cancel取消CEF原生请求,自行用HttpClient转发的逻辑是符合CEFSharp的扩展规范的。
2. IRequest转HttpRequestMessage的正确写法
你当前的头处理写法存在问题:HttpRequestMessage分为请求头和内容头两类,Content-Type、Content-Length这类和请求体相关的头不能直接添加到HttpRequestMessage.Headers中,否则会抛出异常。
完整的转换逻辑如下:
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) { // 同步阶段提前读取所有IRequest属性,避免后续被回收 var requestUrl = request.Url; var method = request.Method; var headers = new Dictionary<string, string>(request.Headers.Count); foreach (string key in request.Headers) { headers[key] = request.Headers[key]; } byte[] postBody = null; if (request.PostData != null && request.PostData.Elements.Count > 0) { // 读取请求体内容,multipart表单可按Elements拆分处理,普通请求直接拼接即可 postBody = request.PostData.Elements.SelectMany(e => e.Bytes).ToArray(); } // 构造HttpRequestMessage var hrm = new HttpRequestMessage(new HttpMethod(method), requestUrl); // 添加请求体 if (postBody != null && postBody.Length > 0) { var content = new ByteArrayContent(postBody); // 把内容相关的头添加到Content.Headers中 foreach (var header in headers) { if (header.Key.StartsWith("Content-", StringComparison.OrdinalIgnoreCase)) { content.Headers.TryAddWithoutValidation(header.Key, header.Value); } } hrm.Content = content; } // 添加非内容类请求头 foreach (var header in headers) { if (!header.Key.StartsWith("Content-", StringComparison.OrdinalIgnoreCase)) { hrm.Headers.TryAddWithoutValidation(header.Key, header.Value); } } // 后续异步逻辑使用已经读取好的hrm即可,不要再访问IRequest Task.Factory.StartNew(async() => { are.WaitOne(); var response = await hc.SendAsync(hrm); // 处理响应结果 }); return CefReturnValue.Cancel; }
3. 仅复制头和内容不足够,还需要补充以下配置
- 要根据
IRequest.Method动态设置请求方法,不要写死为HttpMethod.Post,否则GET、PUT等其他类型的请求会出错 - 需要同步Cookie:要么将CEF存储的对应域名Cookie手动添加到请求头,要么给
HttpClient配置和CEF共用的CookieContainer,避免会话丢失导致服务端返回权限错误 - 代理配置要对齐:如果CEF配置了自定义代理,
HttpClient也要使用相同的代理,否则请求链路不一致可能触发服务端的安全校验拦截 - 重定向策略要对齐:
HttpClient的AllowAutoRedirect属性要和CEF的重定向配置保持一致,避免请求结果和原生逻辑不一致
内容的提问来源于stack exchange,提问作者Al Beir
相关产品推荐
相关产品推荐

