如何在 .aspx 网页上进行异步内容更新后在 Chrome 中保留用户脚本修改
How to preserve userscript modifications in Chrome after an asynchronous content update on an .aspx webpage
我正在尝试为我公司的库存系统自动化网页的工作流程。该页面是由 ASP.Net 页面的服务器端逻辑生成的,我无权访问该页面。该页面上有几个字段,可让您输入新的容器条形码、应放入容器中的物品等。每个字段都有一个 onchange
事件侦听器与其相连,它调用页面的 __doPostBack()
函数来验证输入的数据。如果数据通过验证,页面代码将重新提供到目前为止输入的数据,并将焦点设置到表单上的下一个字段。
我想使用 Chrome 中的用户脚本自动执行此页面。我开始使用 ViolentMonkey 注入自定义脚本,但我只能让脚本在初始加载时触发,而不是在每次数据输入后触发。在此之后,我尝试使用 Chrome 本地覆盖更改 __doPostBack()
以尝试捕获自动化页面所需的数据。那也只能工作一次;在填充字段并失去焦点并提供新 HTML 后,它会覆盖 Chrome 的本地副本。
我认为我的问题是由整个页面内容的异步刷新引起的,它消除了注入的用户脚本和 Chrome 的本地覆盖,而没有触发 [=99] 中的正常页面刷新侦听器=] 覆盖或 ViolentMonkey 以重新注入修改后的代码。有没有人对我如何修改 JavaScript 有任何想法,以便它在页面内容被新的 HTML 替换后仍然存在?
P.S。我认为代码本身与这个特定问题无关,但如果有人认为分享客户端代码的有限部分会有所帮助,请告诉我。
编辑 1:这里更深入地介绍了我正在努力完成的工作,以及我目前取得的进展。作为参考,表格如下所示:
我的原计划
用户加载页面。 ViolentMonkey 注入一个用户脚本,该脚本发出一系列提示,收集用户希望输入系统的新条形码范围的数据。 (具体来说,条码前缀、起始条码编号和结束条码编号。)这些值存储在 localStorage
.
中
用户收集并验证此数据后,页面将正常加载。作为参考,表格看起来像这样:
用户正常填写字段。填写完每个字段后(Container Description 字段除外),页面会将焦点推送到下一个字段。 (例如:<script language="javascript"> try { document.getElementById('txtContDesc').focus() } catch (e) { } </script>
。要关注的字段的 id 通过服务器逻辑动态更改。)
我需要收集 User Badge、Container Type 和 Destination Barcode 值,以便稍后在自动执行表单时重新填写它们。我最初的计划是向 Container Description 字段添加一个 onfocus
事件侦听器,因为一旦验证了 Destination Barcode 字段,焦点就会转移到它。此时我将知道用户已成功为 Container Description 字段上方的每个字段输入有效条目,然后我将能够收集这些值并将它们存储在 localStorage
.[=33= 中]
一旦我获得了表单所需的所有数据,我将使用 ViolentMonkey 中的用户脚本和存储在 localStorage
中的数据来试验表单,以跨页面刷新持久保存数据。
其他选择:
元素上的 eventListener
想法行不通,因为每次验证字段时 ASP.NET 都会使用新代码更新页面,从而消除侦听器。它也不会触发刷新,因此 ViolentMonkey 不会重新运行我的用户脚本。
我的另一个想法是修改 doPostBack()
。 doPostBack()
函数看起来像这样(据我所知):
<script type="text/javascript">
var theForm = document.forms['formNewContainer'];
if (!theForm) {
theForm = document.formNewContainer;
}
function __doPostBack(eventTarget, eventArgument) {
console.log("Form submitted");
}
</script>
使用以下 onchange
处理程序在经过验证的字段上调用它:
onchange="javascript:setTimeout('__doPostBack(\'ctl00$newContPage$txtBarcode\',\'\')', 0)"
我的目标是修改 doPostBack()
以保存我需要 localStorage
的信息,然后再执行 doPostBack()
的其余部分而不更改它。
(注意:这里的 doPostBack()
看起来非常简单,所以我想我遗漏了一些关于 ASP.NET 如何在这里工作的信息。但这不在问题范围内,除非它与什么相关我正在努力。)
我能够使用 Chrome 本地覆盖以这种方式成功修改 doPostBack()
,以便在页面加载时为自己提供页面的本地副本,而不是服务器版本。但这仅适用于第一个 doPostBack()
请求。在第一个请求之后,服务器为我提供新代码。与 ViolentMonkey 一样,缺少刷新触发器会阻止 Chrome 本地覆盖重新提供我的本地副本,并且我得到的代码没有 doPostBack()
修改。
这就是我所在的位置。我会尝试像@wOxxOm 建议的那样添加一个全局侦听器,看看它能帮到我什么。
我完全不明白这怎么可能。您需要与创建该网页的人一起工作。
Asp.net 并且服务器端代码将是大量 .net 代码(c# 或 vb.net)。您触发的每个事件都会将后面代码的变量和服务器端会话(或视图状态)值设置为 运行。
这就是 asp.net 页面的工作方式。您 post 返回,页面传输到服务器,然后是 运行s 后面的 .net 代码。该代码将修改页面、修改控件并修改该页面的视图状态。在该代码 运行 之后(比如单击按钮),您的客户端将收到一个全新的页面 - 这将清除您尝试注入的任何 JavaScript。 (你每次都必须 re-inject)。但是,情况变得更糟,因为后面的代码中有相当一部分也会检查并且通常不会容忍页面设置被弄乱,并且会被拒绝。
做到这一点的唯一方法是编写一些桌面软件,该软件将“容纳”或“托管”网页的完整“com”对象副本,因此您可以自动化该给定页面. (即便如此,你还在打一场必败仗)。
提示:
Web 开发、业务逻辑和功能性业务应用程序不是一些简单的标记和 JavaScript(尽管那 2 周的蹩脚 HTML 课程告诉你什么)。
这是一个应用程序,asp.net 应用程序。试图将其视为一些标记和 JavaScript 实际上是很愚蠢的。这不是您为公司编写或构建业务解决方案的方式。
如果您不会编写和修改代码以及 Web 服务器端的东西,请查明该站点是否有某种 Web api 或其他。
但是,真的 - 这很愚蠢,除非这是一些简单的大学项目,或者一些黑掉的 html 页面和一些 JavaScript?忘记这种方法 - 你处理太多服务器端和服务器上的代码。
事实上,如前所述,asp.net 具有相当多的内置功能,可以检查 post 返回的页面是否被弄乱了,而且您永远无法确定您设置的值和运行s 背后的适当数量的代码来设置行值、数据库主键值和一整船状态值,这些状态值可能 100% 保存在基于 class 对象的服务器端 session() 中 -和永远不会暴露在服务器端的对象。
尝试假设修改或假设您可以创建或修改这样的系统,仅使用客户端工具是行不通的 - 它就是行不通。
code behind 运行s,它 re-processes 带有 .net 代码的页面,然后将整个页面发回 - 所有页面都有新的状态值等。这不是一些蹩脚的 html + JavaScript,但它是用 c# .net 代码编写的完整服务器端代码驱动系统。
我最终使用了一个名为“运行 Javascript”的 Chrome 扩展(它的标志是一头大象),它运行 JavaScript 代码甚至在 AJAX 请求。
Link: https://chrome.google.com/webstore/detail/run-javascript/lmilalhkkdhfieeienjbiicclobibjao/
我正在尝试为我公司的库存系统自动化网页的工作流程。该页面是由 ASP.Net 页面的服务器端逻辑生成的,我无权访问该页面。该页面上有几个字段,可让您输入新的容器条形码、应放入容器中的物品等。每个字段都有一个 onchange
事件侦听器与其相连,它调用页面的 __doPostBack()
函数来验证输入的数据。如果数据通过验证,页面代码将重新提供到目前为止输入的数据,并将焦点设置到表单上的下一个字段。
我想使用 Chrome 中的用户脚本自动执行此页面。我开始使用 ViolentMonkey 注入自定义脚本,但我只能让脚本在初始加载时触发,而不是在每次数据输入后触发。在此之后,我尝试使用 Chrome 本地覆盖更改 __doPostBack()
以尝试捕获自动化页面所需的数据。那也只能工作一次;在填充字段并失去焦点并提供新 HTML 后,它会覆盖 Chrome 的本地副本。
我认为我的问题是由整个页面内容的异步刷新引起的,它消除了注入的用户脚本和 Chrome 的本地覆盖,而没有触发 [=99] 中的正常页面刷新侦听器=] 覆盖或 ViolentMonkey 以重新注入修改后的代码。有没有人对我如何修改 JavaScript 有任何想法,以便它在页面内容被新的 HTML 替换后仍然存在?
P.S。我认为代码本身与这个特定问题无关,但如果有人认为分享客户端代码的有限部分会有所帮助,请告诉我。
编辑 1:这里更深入地介绍了我正在努力完成的工作,以及我目前取得的进展。作为参考,表格如下所示:
我的原计划
用户加载页面。 ViolentMonkey 注入一个用户脚本,该脚本发出一系列提示,收集用户希望输入系统的新条形码范围的数据。 (具体来说,条码前缀、起始条码编号和结束条码编号。)这些值存储在
中localStorage
.用户收集并验证此数据后,页面将正常加载。作为参考,表格看起来像这样:
用户正常填写字段。填写完每个字段后(Container Description 字段除外),页面会将焦点推送到下一个字段。 (例如:
<script language="javascript"> try { document.getElementById('txtContDesc').focus() } catch (e) { } </script>
。要关注的字段的 id 通过服务器逻辑动态更改。)我需要收集 User Badge、Container Type 和 Destination Barcode 值,以便稍后在自动执行表单时重新填写它们。我最初的计划是向 Container Description 字段添加一个
onfocus
事件侦听器,因为一旦验证了 Destination Barcode 字段,焦点就会转移到它。此时我将知道用户已成功为 Container Description 字段上方的每个字段输入有效条目,然后我将能够收集这些值并将它们存储在localStorage
.[=33= 中]一旦我获得了表单所需的所有数据,我将使用 ViolentMonkey 中的用户脚本和存储在
localStorage
中的数据来试验表单,以跨页面刷新持久保存数据。
其他选择:
元素上的 eventListener
想法行不通,因为每次验证字段时 ASP.NET 都会使用新代码更新页面,从而消除侦听器。它也不会触发刷新,因此 ViolentMonkey 不会重新运行我的用户脚本。
我的另一个想法是修改 doPostBack()
。 doPostBack()
函数看起来像这样(据我所知):
<script type="text/javascript">
var theForm = document.forms['formNewContainer'];
if (!theForm) {
theForm = document.formNewContainer;
}
function __doPostBack(eventTarget, eventArgument) {
console.log("Form submitted");
}
</script>
使用以下 onchange
处理程序在经过验证的字段上调用它:
onchange="javascript:setTimeout('__doPostBack(\'ctl00$newContPage$txtBarcode\',\'\')', 0)"
我的目标是修改 doPostBack()
以保存我需要 localStorage
的信息,然后再执行 doPostBack()
的其余部分而不更改它。
(注意:这里的 doPostBack()
看起来非常简单,所以我想我遗漏了一些关于 ASP.NET 如何在这里工作的信息。但这不在问题范围内,除非它与什么相关我正在努力。)
我能够使用 Chrome 本地覆盖以这种方式成功修改 doPostBack()
,以便在页面加载时为自己提供页面的本地副本,而不是服务器版本。但这仅适用于第一个 doPostBack()
请求。在第一个请求之后,服务器为我提供新代码。与 ViolentMonkey 一样,缺少刷新触发器会阻止 Chrome 本地覆盖重新提供我的本地副本,并且我得到的代码没有 doPostBack()
修改。
这就是我所在的位置。我会尝试像@wOxxOm 建议的那样添加一个全局侦听器,看看它能帮到我什么。
我完全不明白这怎么可能。您需要与创建该网页的人一起工作。
Asp.net 并且服务器端代码将是大量 .net 代码(c# 或 vb.net)。您触发的每个事件都会将后面代码的变量和服务器端会话(或视图状态)值设置为 运行。
这就是 asp.net 页面的工作方式。您 post 返回,页面传输到服务器,然后是 运行s 后面的 .net 代码。该代码将修改页面、修改控件并修改该页面的视图状态。在该代码 运行 之后(比如单击按钮),您的客户端将收到一个全新的页面 - 这将清除您尝试注入的任何 JavaScript。 (你每次都必须 re-inject)。但是,情况变得更糟,因为后面的代码中有相当一部分也会检查并且通常不会容忍页面设置被弄乱,并且会被拒绝。
做到这一点的唯一方法是编写一些桌面软件,该软件将“容纳”或“托管”网页的完整“com”对象副本,因此您可以自动化该给定页面. (即便如此,你还在打一场必败仗)。
提示: Web 开发、业务逻辑和功能性业务应用程序不是一些简单的标记和 JavaScript(尽管那 2 周的蹩脚 HTML 课程告诉你什么)。
这是一个应用程序,asp.net 应用程序。试图将其视为一些标记和 JavaScript 实际上是很愚蠢的。这不是您为公司编写或构建业务解决方案的方式。
如果您不会编写和修改代码以及 Web 服务器端的东西,请查明该站点是否有某种 Web api 或其他。
但是,真的 - 这很愚蠢,除非这是一些简单的大学项目,或者一些黑掉的 html 页面和一些 JavaScript?忘记这种方法 - 你处理太多服务器端和服务器上的代码。
事实上,如前所述,asp.net 具有相当多的内置功能,可以检查 post 返回的页面是否被弄乱了,而且您永远无法确定您设置的值和运行s 背后的适当数量的代码来设置行值、数据库主键值和一整船状态值,这些状态值可能 100% 保存在基于 class 对象的服务器端 session() 中 -和永远不会暴露在服务器端的对象。
尝试假设修改或假设您可以创建或修改这样的系统,仅使用客户端工具是行不通的 - 它就是行不通。
code behind 运行s,它 re-processes 带有 .net 代码的页面,然后将整个页面发回 - 所有页面都有新的状态值等。这不是一些蹩脚的 html + JavaScript,但它是用 c# .net 代码编写的完整服务器端代码驱动系统。
我最终使用了一个名为“运行 Javascript”的 Chrome 扩展(它的标志是一头大象),它运行 JavaScript 代码甚至在 AJAX 请求。
Link: https://chrome.google.com/webstore/detail/run-javascript/lmilalhkkdhfieeienjbiicclobibjao/