如何在C#中评估Javascript?(需要获取网页的所有链接,包括java脚本生成的链接)
背景:我必须下载网页及其资源以供脱机查看,但是作为这项工作的一部分,我必须“重写”HTML网页链接的URL,以便它们工作。这比标准类型的链接更好,但是我现在意识到有些链接是由javascript动态创建的 问题:我可以使用什么方法(甚至现有库)将动态生成链接的网页(从javascript)转录到具有正常非动态链接的网页。 (那样我就可以做我需要做的URL重写) 注:如何在C#中评估Javascript?(需要获取网页的所有链接,包括java脚本生成的链接),c#,javascript,url-rewriting,hyperlink,webpage,C#,Javascript,Url Rewriting,Hyperlink,Webpage,背景:我必须下载网页及其资源以供脱机查看,但是作为这项工作的一部分,我必须“重写”HTML网页链接的URL,以便它们工作。这比标准类型的链接更好,但是我现在意识到有些链接是由javascript动态创建的 问题:我可以使用什么方法(甚至现有库)将动态生成链接的网页(从javascript)转录到具有正常非动态链接的网页。 (那样我就可以做我需要做的URL重写) 注: 这几乎就像我需要一个Javascript解释器库,我将页面HTML传递给它,然后它可能会吐出生成的java代码?然后我可以按照自
- 这几乎就像我需要一个Javascript解释器库,我将页面HTML传递给它,然后它可能会吐出生成的java代码?然后我可以按照自己的意愿重写链接(结果将不会使用javascript动态方法)
- 上下文是一个C#WinForms(3.5)应用程序李>
<script type="text/javascript">
<!--
document.write("<a href=\"/home.asp\" onMouseOver=\"MM_swapImage('tab_home','','/_includes/images/tab_home_.gif',1)\" onMouseOut=\"MM_swapImgRestore()\"><img src=\"/includes/images/tab_home.gif\" alt=\"Home\" name=\"tab_home\" width=\"45\" height=\"18\" border=\"0\" id=\"tab_home\"><\/a>");
if (window.document.location.pathname.indexOf("mysite.asp") != "-1") {
document.write("<a href=\"/mysite.asp\" onMouseOver=\"MM_swapImage('tab_my_site','','/_includes/images/tab_my_site_.gif',1)\" onMouseOut=\"MM_swapImgRestore()\"><img src=\"/_includes/images/tab_my_site_.gif\" alt=\"My Site\" name=\"tab_my_site\" width=\"76\" height=\"18\" border=\"0\" id=\"tab_my_site\"><\/a>");
}
else {
document.write("<a href=\"/mysite.asp\" onMouseOver=\"MM_swapImage('tab_my_site','','/_includes/images/tab_my_site_.gif',1)\" onMouseOut=\"MM_swapImgRestore()\"><img src=\"/_includes/images/tab_my_site.gif\" alt=\"My Site\" name=\"tab_my_site\" width=\"76\" height=\"18\" border=\"0\" id=\"tab_my_site\"><\/a>");
}
如果您不使用WebBrowser控件,您可能可以在JScript.NET中使用JScript evaluate方法,但您可能需要计算的不仅仅是一个简单的表达式。WebBrowser控制当然是更简单的路线
如果您使用的是WebBrowser控件,那么可以很容易地从C#调用“eval”方法
/// <summary>
/// Handles the Navigated event of the browser control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="T:WebBrowserNavigatedEventArgs"/> instance containing the
/// event data.</param>
private void browser_Navigated( object sender, WebBrowserNavigatedEventArgs e )
{
string codeToEval = "window.alert('blah')";
if ( browser.Document != null ) {
object window = browser.Document.Window.DomWindow;
if ( window != null ) {
Type windowType = window.GetType();
BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Instance;
string[] args = { codeToEval, "JScript" };
windowType.InvokeMember( "[DispID=1165]", flags, null, window, args );
} // if
} // if
}
//
///处理浏览器控件的导航事件。
///
///事件的来源。
///包含
///事件数据。
已导航的专用无效浏览器(对象发送器,WebBrowserNavigatedEventArgs e)
{
字符串codeToEval=“window.alert('blah')”;
if(browser.Document!=null){
对象窗口=browser.Document.window.DomWindow;
如果(窗口!=null){
类型windowType=window.GetType();
BindingFlags=BindingFlags.InvokeMethod | BindingFlags.Instance;
字符串[]args={codeToEval,“JScript”};
InvokeMember(“[DispID=1165]”,标志,null,窗口,参数);
}//如果
}//如果
}
还有第三种选择。您可以随时按原样下载HTML页面,而无需重新编写URL。然后,在向用户呈现HTML的代码中,您可以捕获对链接的单击并取消导航,然后导航到相应的“脱机”链接。谢谢-我将对此进行研究。那么,我可以使用这个控件而不必在表单中显示它的想法是什么呢?因为这是一个引擎盖下的程序,不应该向用户显示。好吧,线程问题放在一边,是的,你可以使用一个完全自动和隐藏的WebBrowser控件,而不向用户显示。它当然会比纯HTTP请求慢,因为它将通过DOM、渲染引擎和脚本引擎(这正是您所需要的)。我想您也可以在不使用WebBrowser的情况下尝试MSHTML对象模型。这两个选项都需要一个STA线程,可能还需要一个消息循环,所以一定要在Winforms主线程中完成工作。嗯……只执行jvascript本身怎么样?我将使用页面HTML+其他JS文件/页面引用的文本。事实上,您可能会认为JavaScript引擎/库只需要执行基本的字符串操作?对,但是如果生成链接的表达式依赖于页面事件呢。例如,在jQuery中,创建元素以响应客户端需要复制的DOM事件是非常常见的。这就是为什么WebBrowser控件(或者可能是MSHTML)要简单得多的原因,因为您实际上是在一个具有完全自动化功能的实际浏览器中加载页面。呃..绘图不断加厚..我在文章中添加了一些来自网页的示例
<td width="1%">
<a href="javascript:checksubmit(this);"
onmouseover="MM_swapImage('but_srch_go','','/_includes/images/but_srch_go_.gif',1)"
onmouseout="MM_swapImgRestore()">
<img src="http://localhost:3000/sites/http://qheps.health.qld.gov.au/_includes/images/but_srch_go.gif" alt="Go" name="but_srch_go" width="57" height="40" border="0">
</a>
</td>
/// <summary>
/// Handles the Navigated event of the browser control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="T:WebBrowserNavigatedEventArgs"/> instance containing the
/// event data.</param>
private void browser_Navigated( object sender, WebBrowserNavigatedEventArgs e )
{
string codeToEval = "window.alert('blah')";
if ( browser.Document != null ) {
object window = browser.Document.Window.DomWindow;
if ( window != null ) {
Type windowType = window.GetType();
BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Instance;
string[] args = { codeToEval, "JScript" };
windowType.InvokeMember( "[DispID=1165]", flags, null, window, args );
} // if
} // if
}