【问题标题】:Supress JS alerts when using Invoke-WebRequest使用 Invoke-WebRequest 时抑制 JS 警报
【发布时间】:2018-06-18 14:42:22
【问题描述】:

这是我观察到的非常奇怪的行为。当网页中只有以下内容时,Invoke-WebRequest 将发出警报消息并暂停所有脚本,直到解除警报。

<script>
alert('testing');
</script>

我在网上找到了一个例子,所以你们都可以轻松复制。

Invoke-WebRequest 'http://activelab.io/code-snippets/show-alert-box-on-page-load'

这是最奇怪的一点。我已经尝试了很多来避免这种警报。 -UseBasicParsing 在我的情况下不是一个选项。因此,我尝试将对象分配给一个变量,并仅访问未提及警报的部分。例如:

$x = Invoke-WebRequest 'http://activelab.io/code-snippets/show-alert-box-on-page-load'
$x.Forms

但这仍然会生成警报消息!即使$null = $x.Forms 或类似的技巧也无法阻止它。

即使是陌生人,也只会返回一次。比如:

$x = Invoke-WebRequest 'http://activelab.io/code-snippets/show-alert-box-on-page-load'
$x.Forms
$x.Forms
$x.Forms

返回一条消息。只有当我重新调用请求时,我才会收到额外的错误。

我也尝试在作业中运行它,但这仍然会产生警报。作业会暂停,直到被解雇。

是否有人知道如何在不使用-UseBasicParsing 参数的情况下解决此问题?

【问题讨论】:

  • 您能否详细说明为什么 -UseBasicParsing 对您不可用?
  • @oɔɯǝɹ -UseBasicParsing 不会填充 $request.Forms,这意味着我必须实现 HTML/JS 解析来确定输入字段。
  • 啊,所以你想遍历表单/字段?
  • @oɔɯǝɹ 没错,虽然我认为这与问题不太相关,真的。我觉得这应该是可以解决的,而不仅仅是为我的具体案例创建解决方法。
  • 也许使用 -UseBasicParsing 将 HTML 下载到本地文件并解析使用 DOM 是一种选择? social.technet.microsoft.com/wiki/contents/articles/…

标签: powershell


【解决方案1】:

拨打电话-UseBasicParsing

$Request = Invoke-WebRequest 'http://activelab.io/code-snippets/show-alert-box-on-page-load' -UseBasicParsing

*编辑:我知道你说过你不能使用-UseBasicParsing,但这里的重点是你不必实现自己的解析。您可以使用与 Invoke-WebRequest 在修改响应后使用的相同解析以避免警报。这样您就可以在没有任何警报的情况下填充$request.forms

修改响应 HTML 以覆盖警报弹出窗口。

$JavascriptAlertOverride = @"
// Override window.alert
  window.alert = function() {
    // do nothing here
  };

// Override alert
  alert = function() {
    // do nothing here
  };
"@
$NonAlertingHTML = $Request.Content -replace "<head>", "<head><script type='text/javascript'>$JavascriptAlertOverride</script>"

然后将其解析回完整的 IHTMLDocument,您现在将可以访问 .forms 以及 Invoke-WebRequest 上的任何其他属性,除非您不会收到警报。

$HTML = New-Object -ComObject "HTMLFile"
$HTML.IHTMLDocument2_write($NonAlertingHTML)
$HTML.forms

PS > $HTML.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                  
-------- -------- ----                                     --------                                                                                                                  
True     False    HTMLDocumentClass                        System.__ComObject                                                                                                        



PS > $Request.ParsedHtml.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                  
-------- -------- ----                                     --------                                                                                                                  
True     False    HTMLDocumentClass                        System.__ComObject 

【讨论】:

  • 您没有正确阅读 OP。引用:"-UseBasicParsing 在我的情况下不是一个选项。"
  • 我确实读过它,但我也读过他关于为什么他认为他不能使用它的评论“-UseBasicParsing 不会填充 $request.Forms,这意味着我必须实现 HTML/JS解析以确定输入字段”意味着他不知道他不必实现自己的解析。他可以使用与 Invoke-WebRequest 在修改响应后所做的相同的解析引擎。我会尝试在答案中澄清这一点,如果他碰巧在 2.0 上,而 -UseBasicParsing 实际上不是一个选项,我会写另一个选项。
  • 最后我不得不将它授予@tukan,但通过一些额外的工作,我认为这是一个很好的解决方案。您仍然需要解析树,所以我想这取决于 HTMLDocument 将如何构建不同的树。我相信 HtmlWebResponseObject 在这里仍然更标准。
  • @JacobColvin 谢谢。我也对此投了赞成票,因为它是有趣的贡献。
【解决方案2】:

'https://www.quackit.com/javascript/javascript_alert_box_example_2.cfm' 的 SSL 存在问题。我得到:

Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.

At line:1 char:1
+ Invoke-WebRequest -uri 'https://www.quackit.com/javascript/javascript_alert_box_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

我必须将其更改为:'https://64.73.217.183/javascript/javascript_alert_box_example_2.cfm' 然后我可以在 PS 4.x 中对其进行测试。

这个想法怎么样 - 使用Try{} Catch{}

Try {
    Invoke-WebRequest -uri 'https://64.73.217.183/javascript/javascript_alert_box_example_2.cfm'
} Catch {
 "$_"
}

由于“$_”只产生简单的

底层连接已关闭:发送时发生意外错误。

如果您不想出现任何错误,只需删除或标记"$_"

如果您想要有关 powershell 错误处理的完整资源,您应该阅读The Big Book of PowerShell Error Handling

重新编辑 显然关闭alert 框并不容易。根据我的调查,它似乎是 powershell 中的一种 iexplorer 实例。

在我看来,根据我的研究,没有办法“抑制”显示的警报窗口。

但是,您可以这样做(一种解决方法):

一个脚本是原始的:

$x = Invoke-WebRequest -uri 'http://activelab.io/code-snippets/show-alert-box-on-page-load'
$x.Forms

第二种是关闭窗口(需要有WASP(Windows Automation Snap-in for Powershell)模块):

Import-Module WASP
start-Sleep -Seconds 15
$web_alert = Get-Process | Where-Object { $_.MainWindowTitle -
Like 'Message from webpage' } # this is what identifies the window (based on your example)
select-window $web_alert | Set-windowActive | send-keys '{Enter}' # press enter

然后有第三个类似这些行的东西,它应该在后台异步启动脚本(这只是一个快速镜头,你可以像PoshRSJob这样花哨的东西:

$jobA = Start-Process PowerShell -Argument 'C:\script1.ps1'
$jobB = Start-Process PowerShell -Argument 'C:\script2.ps1'

【讨论】:

  • 我想这就是我使用一些随机人的网站所得到的。我编辑了指向演示该行为的非 SSL 站点的链接。不幸的是,它不使用 powershell 的事件处理程序,所以我无法捕捉到它。
  • @JacobColvin 之前的链接在 powershell 中生成了错误。如果你得到一个窗口,那么情况就不同了,但仍然可以通过 try and catch 块捕获。我会更新答案。您能否详细说明为什么 -UseBasicParsing 不适合您?
  • -UseBasicParsing 不会填充$request.Forms,这意味着我必须实现 HTML/JS 解析来确定输入字段。
  • @JacobColvin 现在我明白你想做什么了...... :)
  • 你的 try/catch 也没有捕捉到任何东西。输出 $x 或 $x 的任何孩子,窗口仍然会出现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 2018-07-27
  • 2020-07-02
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多