__doPostBack用法感悟

本文详细介绍了ASP.NET中的__doPostBack函数,解释了其如何帮助客户端控件调用服务器端事件,尤其关注LinkButton控件的工作原理及如何利用__doPostBack实现自动回传。

今天遇到了__doPostBack函数,在网上看到了很多关于__doPostBack使用的方法,但是感觉说法都有些出入,或者不清楚。因此也让我这个本来一向喜欢引用别人东西的人忍不住要在自己的博客里面留下自己的一点原创了。。

言归正传,首先要记住这个函数的前面是两个下划线. __doPostBack=  "_" + "_" + "doPostBack".

再介绍一下__doPostBack函数的作用。我们先来看一下_doPostBack函数的内容:

<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE4NDIzMDg2NDRkZMlHJoBQ9CYcWBtBK+zrfZzKoh/i" />
</div>

<script type="text/javascript">
<!--
var theForm = document.forms['form1'];
if (!theForm) {
    theForm 
= document.form1;
}

function __doPostBack(eventTarget, eventArgument) {
    
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value 
= eventTarget;
        theForm.__EVENTARGUMENT.value 
= eventArgument;
        theForm.submit();
    }

}

// -->
</script>
    
<div>

上面这段是直接从含有自动回传功能控件的.net Web页面的HTML源代码里面粘帖过来的。

其中eventTarget 和eventArgument,是两个就是用来存储在回送的时候获取是哪个控件触发了回送,并且带了什么参数。总之,调用__doPostBack函数可以实现客户端控件调用服务器端控件的响应。或者是在javascript里面调用.net的服务器控件事件。这一点可以充分用在子窗口调用父窗口中某个服务器控件的服务器端的事件。

 然后我们可以从LinkButton这个控件入手,分析一下 LinkButton的工作流程,就知道__doPostBack的使用方法了。因为微软的LinkButton就是使用__doPostBack函数来达到使用客户端的控件来调用服务器端的函数的。

我们可以运行一个包含有LinkButton的aspx页面,查看他的源代码,发现关于LinkButton这个控件的代码竟然是一个超链接:

aspx中LinkButton的代码:
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click">button1</asp:LinkButton>
在html中的源码中被翻译成了:
<id="LinkButton1" href="javascript:__doPostBack('LinkButton1','')">button1</a>

上面的代码可以明显的看出,LinkButton只不过就是一个超链接,他的链接就是执行javascript语句通过调用__doPostBack函数来调用服务器端的后台代码的。因此,在有LinkButton的页面,会自动加上上面的__doPostBack函数。

但是在我们调用__doPostBack函数时,有些时候调用这个函数会出现"对象不存在"的脚本错误? 那是因为Html里面没有__doPostBack函数体,一般在拖放那些有自动回传功能的控件时,当把他的autoPostback属性设为True,在运行的时候系统会自动添加__doPostback函数体,当然最直接的办法就是添加一个LinkButton然后把其Text属性设为空,切记不要设Visible属性,因为如果Visible=false,在翻译成Html时,直接就忽略LinkButton的存在了。

在Web自动化测试或爬虫中,模拟触发 `__doPostBack` 点击事件通常涉及对页面 JavaScript 逻辑的深入理解。`__doPostBack` 是 ASP.NET 中用于触发页面回发(Postback)的核心函数,其本质是一个 JavaScript 函数,用于向服务器提交页面数据并重新加载部分内容或整个页面[^1]。 ### 模拟触发 `__doPostBack` 的方法 #### 1. 直接调用 `__doPostBack` 函数 在自动化脚本中,可以通过执行 JavaScript 来直接调用 `__doPostBack` 函数。例如,在使用 Selenium 进行浏览器自动化时,可以使用如下代码: ```python from selenium import webdriver driver = webdriver.Chrome() driver.get("http://example.com") # 模拟调用 __doPostBack 函数 driver.execute_script("__doPostBack('ctl00$MainContent$Button1', '')") ``` 上述代码中,`execute_script` 方法用于执行页面上的 JavaScript 代码,其中 `'ctl00$MainContent$Button1'` 是触发回发的控件的 `UniqueID`,第二个参数通常为空字符串(用于传递事件参数)[^1]。 #### 2. 模拟点击控件 如果目标控件具有 `onclick` 事件,并且该事件调用了 `__doPostBack`,则可以直接通过自动化工具点击该控件。例如: ```python from selenium import webdriver driver = webdriver.Chrome() driver.get("http://example.com") # 找到按钮并点击 button = driver.find_element("name", "ctl00$MainContent$Button1") button.click() ``` 这种方式更接近用户行为,适用于大多数 ASP.NET Web Forms 控件。 #### 3. 使用 Headless 浏览器模拟 在爬虫场景中,可以使用 Headless 浏览器(如 Puppeteer 或 Playwright)来模拟完整的浏览器环境,并触发 `__doPostBack`。例如,使用 Puppeteer(Node.js): ```javascript const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.goto('http://example.com'); // 模拟点击按钮 await page.click('#ctl00_MainContent_Button1'); // 等待页面加载完成 await page.waitForNavigation(); // 获取页面内容 const content = await page.content(); console.log(content); await browser.close(); })(); ``` 此方法适合需要完整页面渲染和 JavaScript 执行的复杂场景。 ### 注意事项 - **参数识别**:`__doPostBack` 通常接受两个参数:控件的 `UniqueID` 和事件参数。可以通过浏览器开发者工具查看页面源代码,找到具体的参数值。 - **页面状态管理**:ASP.NET 页面在回发时会维护页面状态(ViewState),因此在自动化操作中需要确保页面状态正确传递。 - **事件验证**:某些页面可能启用 `EventValidation`,这会限制非法的回发事件。此时,需要确保发送的参数在服务器端允许的范围内。 ### 示例:使用 Selenium 模拟 `__doPostBack` 并获取响应 ```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.get("http://example.com") # 等待页面加载完成 wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.TAG_NAME, 'body'))) # 模拟触发 __doPostBack driver.execute_script("__doPostBack('ctl00$MainContent$Button1', '')") # 等待页面重新加载 wait.until(EC.staleness_of(driver.find_element(By.TAG_NAME, 'body'))) wait.until(EC.presence_of_element_located((By.TAG_NAME, 'body'))) # 获取更新后的内容 content = driver.page_source print(content) driver.quit() ``` ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值