Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在任何文档加载/处理之前插入Javascript_Javascript_C#_Cefsharp_Javascript Injection - Fatal编程技术网

在任何文档加载/处理之前插入Javascript

在任何文档加载/处理之前插入Javascript,javascript,c#,cefsharp,javascript-injection,Javascript,C#,Cefsharp,Javascript Injection,对于我正在进行的项目,我需要在任何网页文档处理开始之前注入javascript。这可以通过WebBrowser组件轻松实现,但我在使用CefSharp时遇到了困难 这里是问题的简化,一个网页需要一个“InjectedObject”来实现功能。在文档顶部调用网页而不进行注入,或在处理文档之前对其进行评估/执行,将导致: ====失败时的html示例输出===== 你在场吗 假的 ===== 当我需要网页显示时,在哪里: ====成功时的html示例输出===== 你在场吗 真的 ===== 然而,

对于我正在进行的项目,我需要在任何网页文档处理开始之前注入javascript。这可以通过WebBrowser组件轻松实现,但我在使用CefSharp时遇到了困难

这里是问题的简化,一个网页需要一个“InjectedObject”来实现功能。在文档顶部调用网页而不进行注入,或在处理文档之前对其进行评估/执行,将导致:

====失败时的html示例输出=====

你在场吗

假的

=====

当我需要网页显示时,在哪里:

====成功时的html示例输出=====

你在场吗

真的

=====

然而,我尝试过的所有迭代,甚至使用FrameLoadStart,都会导致在文档开始处理之后插入javascript。是否有任何真正的javascript注入的例子确保它发生在文档处理开始之前。(确保避免出现竞速条件/正时问题)

我希望模仿的WebBrowser组件行为示例如下:

private void uiWebBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e) 
{
  var browser = (WebBrowser)sender;
  var document = browser.Document as HTMLDocument;
  var head = document.getElementsByTagName("head").Cast<HTMLHeadElement>().First();
  if (head != null)
  {
    var script = document.createElement("script") as IHTMLScriptElement;
    script.text = "window.InjectedObject = {};"
    if (head.firstChild != null)
    {
      head.insertBefore((IHTMLDOMNode)script, head.firstChild);
    }
    else
    {
      head.appendChild((IHTMLDOMNode)script;
    }
  }
}

我非常感谢这些评论和建议。如果我遗漏了什么,请告诉我

终于回到了这个话题。主要基于以下示例:

实现IRequestHandler和IResponseFilter接口:

==MainWindow.xaml==

<Window x:Class="ExampleCefSharp001.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ExampleCefSharp001"
    mc:Ignorable="d"
    Title="MainWindow" Height="1000" Width="1100">
  <Grid>
    <cefSharp:ChromiumWebBrowser x:Name="uiWebView"></cefSharp:ChromiumWebBrowser>
  </Grid>
</Window>
<Window x:Class="ExampleCefSharp001.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:local="clr-namespace:ExampleCefSharp001"
  mc:Ignorable="d"
  Title="MainWindow" Height="1000" Width="1100">
  <Grid>
    <cefSharp:ChromiumWebBrowser x:Name="uiWebView"></cefSharp:ChromiumWebBrowser>
  </Grid>
</Window>

==MainWindow.xaml.cs==

public partial class MainWindow : Window
{
  JavascriptManager jsmanager;

  public MainWindow()
  {
    InitializeComponent();

    jsmanager = new JavascriptManager(uiWebView);
  }
}

public class JavascriptManager : ILoadHandler, IRenderProcessMessageHandler
{
  string injection = "window.InjectedObject = {};";

  public JavascriptManager(ChromiumWebBrowser browser)
  {
    browser.LoadHandler = this;
    browser.RenderProcessMessageHandler = this;

    //  Lets just pretend this is a real url with the example html above.
    browser.Address = "https://www.example.com/timingtest.htm"
  }

  public void OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame)
  {
    frame.ExecuteJavaScriptAsync(injection);
  }
}
public partial class MainWindow : Window
{
  JavascriptManager jsmanager;

  public MainWindow()
  {
    InitializeComponent();

    jsmanager = new JavascriptManager(uiWebView);
  }
}

public class JavascriptManager : IRequestHandler
{
  string injection = "window.InjectedObject = {};";

  public JavascriptManager(ChromiumWebBrowser browser)
  {
    browser.RequestHandler = this;

    //  Lets just pretend this is a real url with the example html above.
    browser.Address = "https://www.example.com/timingtest.htm"
  }

  public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
    {
        if (frame.IsMain && request.ResourceType == ResourceType.MainFrame) 
        {
            return new JavascriptInjectionFilter(injection);
        }
        return null;
    }
}

public class JavascriptInjectionFilter : IResponseFilter
{
    /// <summary>
    /// Location to insert the javascript
    /// </summary>
    public enum Locations
    {
        /// <summary>
        /// Insert Javascript at the top of the header element
        /// </summary>
        head,
        /// <summary>
        /// Insert Javascript at the top of the body element
        /// </summary>
        body
    }

    string injection;
    string location;
    int offset = 0;
    List<byte> overflow = new List<byte>();

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="injection"></param>
    /// <param name="location"></param>
    public JavascriptInjectionFilter(string injection, Locations location = Locations.head)
    {
        this.injection = "<script>" + injection + "</script>";
        switch (location)
        {
            case Locations.head:
                this.location = "<head>";
                break;

            case Locations.body:
                this.location = "<body>";
                break;

            default:
                this.location = "<head>";
                break;
        }
    }

    /// <summary>
    /// Disposal
    /// </summary>
    public void Dispose()
    {
        //
    }

    /// <summary>
    /// Filter Processing...  handles the injection
    /// </summary>
    /// <param name="dataIn"></param>
    /// <param name="dataInRead"></param>
    /// <param name="dataOut"></param>
    /// <param name="dataOutWritten"></param>
    /// <returns></returns>
    public FilterStatus Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
    {
        dataInRead = dataIn == null ? 0 : dataIn.Length;
        dataOutWritten = 0;

        if (overflow.Count > 0)
        {
            var buffersize = Math.Min(overflow.Count, (int)dataOut.Length);
            dataOut.Write(overflow.ToArray(), 0, buffersize);
            dataOutWritten += buffersize;

            if (buffersize < overflow.Count)
            {
                overflow.RemoveRange(0, buffersize - 1);
            }
            else
            {
                overflow.Clear();
            }
        }


        for (var i = 0; i < dataInRead; ++i)
        {
            var readbyte = (byte)dataIn.ReadByte();
            var readchar = Convert.ToChar(readbyte);
            var buffersize = dataOut.Length - dataOutWritten;

            if (buffersize > 0)
            {
                dataOut.WriteByte(readbyte);
                dataOutWritten++;
            }
            else
            {
                overflow.Add(readbyte);
            }

            if (char.ToLower(readchar) == location[offset])
            {
                offset++;
                if (offset >= location.Length)
                {
                    offset = 0;
                    buffersize = Math.Min(injection.Length, dataOut.Length - dataOutWritten);

                    if (buffersize > 0)
                    {
                        var data = Encoding.UTF8.GetBytes(injection);
                        dataOut.Write(data, 0, (int)buffersize);
                        dataOutWritten += buffersize;
                    }

                    if (buffersize < injection.Length)
                    {
                        var remaining = injection.Substring((int)buffersize, (int)(injection.Length - buffersize));
                        overflow.AddRange(Encoding.UTF8.GetBytes(remaining));
                    }

                }
            }
            else
            {
                offset = 0;
            }

        }

        if (overflow.Count > 0 || offset > 0)
        {
            return FilterStatus.NeedMoreData;
        }

        return FilterStatus.Done;
    }

    /// <summary>
    /// Initialization
    /// </summary>
    /// <returns></returns>
    public bool InitFilter()
    {
        return true;
    }

}
公共部分类主窗口:窗口
{
JavascriptManager和jsmanager;
公共主窗口()
{
初始化组件();
jsmanager=newJavaScriptManager(uiWebView);
}
}
公共类JavascriptManager:IRequestHandler
{
字符串注入=“window.InjectedObject={};”;
公共JavascriptManager(ChromiumWebBrowser浏览器)
{
browser.RequestHandler=this;
//让我们假设这是一个真实的url,上面的例子是html。
浏览器地址=”https://www.example.com/timingtest.htm"
}
公共IResponseFilter GetResourceResponseFilter(IWebBrowser浏览器控件、IBrowser浏览器、IFrame框架、IRequest请求、IResponse响应)
{
if(frame.IsMain&&request.ResourceType==ResourceType.MainFrame)
{
返回新的JavascriptInjectionFilter(注入);
}
返回null;
}
}
公共类JavascriptInjectionFilter:IResponseFilter
{
/// 
///插入javascript的位置
/// 
公共枚举位置
{
/// 
///在header元素的顶部插入Javascript
/// 
头,,
/// 
///在body元素的顶部插入Javascript
/// 
身体
}
管柱注入;
字符串位置;
整数偏移=0;
列表溢出=新列表();
/// 
///建造师
/// 
/// 
/// 
公共JavascriptInjectionFilter(字符串注入,位置=位置.head)
{
this.injection=“”+injection+”;
开关(位置)
{
案件地点.负责人:
此参数为:location=“”;
打破
案例位置。正文:
此参数为:location=“”;
打破
违约:
此参数为:location=“”;
打破
}
}
/// 
///处置
/// 
公共空间处置()
{
//
}
/// 
///过滤处理…处理注入
/// 
/// 
/// 
/// 
/// 
/// 
公共筛选器Status筛选器(流数据输入、流长数据输入、流数据输出、流长数据输出)
{
dataInRead=dataIn==null?0:dataIn.Length;
dataoutwrited=0;
如果(overflow.Count>0)
{
var buffersize=Math.Min(overflow.Count,(int)dataOut.Length);
写入(overflow.ToArray(),0,buffersize);
DataOutwrited+=缓冲区大小;
if(buffersize0)
{
写字节(读字节);
datawrited++;
}
其他的
{
Add(readbyte);
}
if(char.ToLower(readchar)=位置[offset])
{
offset++;
如果(偏移量>=位置长度)
{
偏移量=0;
buffersize=Math.Min(injection.Length,dataOut.Length-dataoutwrited);
如果(缓冲区大小>0)
{
var data=Encoding.UTF8.GetBytes(注入);
写入(数据,0,(int)buffersize);
DataOutwrited+=缓冲区大小;
}
if(缓冲区大小<注入长度)
{
var剩余=injection.Substring((int)buffersize,(int)(injection.Length-buffersize));
AddRange(Encoding.UTF8.GetBytes(剩余));
}
}
}
其他的
{
偏移量=0;
}
}
如果(overflow.Count>0 | | offset>0)
{
返回FilterStatus.NeedMoreData;
}
返回过滤器状态。完成;
}
/// 
///初始化
/// 
/// 
公共bool InitFilter()
{
返回true;
}
}
谢谢你为我指明了正确的方向,谢谢你
<Window x:Class="ExampleCefSharp001.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:local="clr-namespace:ExampleCefSharp001"
  mc:Ignorable="d"
  Title="MainWindow" Height="1000" Width="1100">
  <Grid>
    <cefSharp:ChromiumWebBrowser x:Name="uiWebView"></cefSharp:ChromiumWebBrowser>
  </Grid>
</Window>
public partial class MainWindow : Window
{
  JavascriptManager jsmanager;

  public MainWindow()
  {
    InitializeComponent();

    jsmanager = new JavascriptManager(uiWebView);
  }
}

public class JavascriptManager : IRequestHandler
{
  string injection = "window.InjectedObject = {};";

  public JavascriptManager(ChromiumWebBrowser browser)
  {
    browser.RequestHandler = this;

    //  Lets just pretend this is a real url with the example html above.
    browser.Address = "https://www.example.com/timingtest.htm"
  }

  public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
    {
        if (frame.IsMain && request.ResourceType == ResourceType.MainFrame) 
        {
            return new JavascriptInjectionFilter(injection);
        }
        return null;
    }
}

public class JavascriptInjectionFilter : IResponseFilter
{
    /// <summary>
    /// Location to insert the javascript
    /// </summary>
    public enum Locations
    {
        /// <summary>
        /// Insert Javascript at the top of the header element
        /// </summary>
        head,
        /// <summary>
        /// Insert Javascript at the top of the body element
        /// </summary>
        body
    }

    string injection;
    string location;
    int offset = 0;
    List<byte> overflow = new List<byte>();

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="injection"></param>
    /// <param name="location"></param>
    public JavascriptInjectionFilter(string injection, Locations location = Locations.head)
    {
        this.injection = "<script>" + injection + "</script>";
        switch (location)
        {
            case Locations.head:
                this.location = "<head>";
                break;

            case Locations.body:
                this.location = "<body>";
                break;

            default:
                this.location = "<head>";
                break;
        }
    }

    /// <summary>
    /// Disposal
    /// </summary>
    public void Dispose()
    {
        //
    }

    /// <summary>
    /// Filter Processing...  handles the injection
    /// </summary>
    /// <param name="dataIn"></param>
    /// <param name="dataInRead"></param>
    /// <param name="dataOut"></param>
    /// <param name="dataOutWritten"></param>
    /// <returns></returns>
    public FilterStatus Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
    {
        dataInRead = dataIn == null ? 0 : dataIn.Length;
        dataOutWritten = 0;

        if (overflow.Count > 0)
        {
            var buffersize = Math.Min(overflow.Count, (int)dataOut.Length);
            dataOut.Write(overflow.ToArray(), 0, buffersize);
            dataOutWritten += buffersize;

            if (buffersize < overflow.Count)
            {
                overflow.RemoveRange(0, buffersize - 1);
            }
            else
            {
                overflow.Clear();
            }
        }


        for (var i = 0; i < dataInRead; ++i)
        {
            var readbyte = (byte)dataIn.ReadByte();
            var readchar = Convert.ToChar(readbyte);
            var buffersize = dataOut.Length - dataOutWritten;

            if (buffersize > 0)
            {
                dataOut.WriteByte(readbyte);
                dataOutWritten++;
            }
            else
            {
                overflow.Add(readbyte);
            }

            if (char.ToLower(readchar) == location[offset])
            {
                offset++;
                if (offset >= location.Length)
                {
                    offset = 0;
                    buffersize = Math.Min(injection.Length, dataOut.Length - dataOutWritten);

                    if (buffersize > 0)
                    {
                        var data = Encoding.UTF8.GetBytes(injection);
                        dataOut.Write(data, 0, (int)buffersize);
                        dataOutWritten += buffersize;
                    }

                    if (buffersize < injection.Length)
                    {
                        var remaining = injection.Substring((int)buffersize, (int)(injection.Length - buffersize));
                        overflow.AddRange(Encoding.UTF8.GetBytes(remaining));
                    }

                }
            }
            else
            {
                offset = 0;
            }

        }

        if (overflow.Count > 0 || offset > 0)
        {
            return FilterStatus.NeedMoreData;
        }

        return FilterStatus.Done;
    }

    /// <summary>
    /// Initialization
    /// </summary>
    /// <returns></returns>
    public bool InitFilter()
    {
        return true;
    }

}
<html><head></head><body><script>window.InjectedObject = {}</script>
  <script>
    isObjectPresent = typeof InjectedObject == "object";
  </script>
  <p>isObjectPresent?</p>
  <div id="result"></div>
  <script>
    document.getElementById("result").innerHTML = isObjectPresent;
  </script>
</body></html>
public class CustomRequestHandler : DefaultRequestHandler
{
    string script = "alert('hello');";

    public override IResponseFilter GetResourceResponseFilter(CefSharp.IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
    {
        if (frame.IsMain && request.ResourceType == ResourceType.MainFrame)
        {
            return new JavascriptInjectionFilter(script);
        }
        return null;
    }
}
CustomRequestHandler customRequestHandler = new CustomRequestHandler();
chromeBrowser.RequestHandler = customRequestHandler ;