子窗口关闭,刷新父窗口

http://shawpnendu.blogspot.com/2009/02/automaticaly-refresh-parent-window.html

 

 

For data driven web application most of the times we did this job. There are lot of way to handle this issue. Here i am trying to show you few process that how we can handle it. To describe this problem here i am using datatable instead of database since anyone can replace my code easily by his own data reader block. Let we have a requirement that a page contains list of suppliers. Below the supplier list client wants to add a link to add more suppliers like:

If user click on add more supplier link then the link open a popup to enter supplier details. After entering the supplier details when user click on the save button then system automatically save the data & close the popup as well as reflect the currently added row to the opener like:

So now we can start step by step. At first add a page named parentrefresh.aspx. Then add a gridview to display the existing suppliers. After the gridview we need to add a link button/html button to popup the window. So parentrefresh.aspx looks like:

<b>List of suppliers:</b>

<asp:GridView runat="server" ID="gvEdit" DataKeyNames="ID" AutoGenerateColumns="false" ">
<Columns>
<asp:BoundField DataField="Code" HeaderText="Code"></asp:BoundField>
<asp:BoundField DataField="Name" HeaderText="Name"></asp:BoundField>
<asp:BoundField DataField="Address" HeaderText="Address"></asp:BoundField>
<asp:BoundField DataField="Contact" HeaderText="Contact no"></asp:BoundField>
</Columns>
</asp:GridView>

<asp:LinkButton runat="server" OnClientClick="window.open('childrefresh.aspx');return false;"
ID="lnkNew">Add more supplier
</asp:LinkButton>


To read existing supplier data from database(here i use datatable for simplicity) we need to write few server side code in page load event. Codes:

if (!IsPostBack)
{
DataTable dtSupplier;
if (Session["dtSupplier"]==null)
{
//If not populated previously then we need to populate data. Otherwise we read from session.
dtSupplier = new DataTable("Supplier");
dtSupplier.Columns.Add(new DataColumn("ID", System.Type.GetType("System.UInt64")));
dtSupplier.Columns.Add(new DataColumn("Code"));
dtSupplier.Columns.Add(new DataColumn("Name"));
dtSupplier.Columns.Add(new DataColumn("Address"));
dtSupplier.Columns.Add(new DataColumn("Contact"));
dtSupplier.Rows.Add(1, "st0001", "S.R. Steel", "Uttara, Dhaka", "01711xxxxxx");
dtSupplier.Rows.Add(2, "ir0039", "Shadesh builders", "Rampura, Dhaka", "01711yyyyyy");
dtSupplier.Rows.Add(3, "cr0042", "Orchard confec.", "Shahabag, Dhaka", "01711zzzzzz");
dtSupplier.Rows.Add(4, "er0078", "Windblow", "Mirpur, Dhaka", "01711qqqqqq");
dtSupplier.Rows.Add(5, "bd0301", "Rahimkarim", "Badda, Dhaka", "01711oooooo");
Session["dtSupplier"] = dtSupplier;
}
else
dtSupplier = (DataTable)Session["dtSupplier"];
gvEdit.DataSource = dtSupplier;
gvEdit.DataBind();
}


Now we need to add another page named childrefresh.aspx which will be our popup window. If you look at the first page link button click event then you found this page url as a popup. Find the child page html contents from below:

The onunload event basically refresh the parent page. Here you can refresh parent page by location or reload by using onunload="window.opener.location.reload();"
Or you can call a javascript function within onunload handler. Initially start with below code. After than practice above ways.

<body onunload="window.opener.location=window.opener.location;">
<form id="form1" runat="server">
<div>
<table border="0">
<tr><td>Code:</td><td>
<asp:TextBox runat="server" ID="txtCode"></asp:TextBox></td></tr>
<tr><td>Name:</td><td>
<asp:TextBox runat="server" ID="txtName"></asp:TextBox>
</td></tr>
<tr><td>Address:</td><td>
<asp:TextBox runat="server" ID="txtAddress"></asp:TextBox></td></tr><tr><td>Contact no:</td><td>
<asp:TextBox runat="server" ID="txtContact"></asp:TextBox></td>
</tr>
</table>
</div>
<asp:LinkButton runat="server" ID="lnkSave" OnClick="lnkSave_Click">Save & close</asp:LinkButton>


Now we need to write few code under save button to add supplier data in session datatable so parent page can read the currently saved data:

protected void Page_Load(object sender, EventArgs e)
{
//session time may be expired/user may open the popup directly other wise page gives error.
if (Session["dtSupplier"] == null)
return;
}

protected void lnkSave_Click(object sender, EventArgs e)
{
DataTable dtSupplier = (DataTable)Session["dtSupplier"];
dtSupplier.Rows.Add(1, txtCode.Text, txtName.Text, txtAddress.Text, txtContact.Text);
Session["dtSupplier"] = dtSupplier;
//below line register the close block in the page which will run imediately & close the popup.
ClientScript.RegisterStartupScript(GetType(),"tst", "<script>window.close();</script>");
}


Now our example is ready. Just run...........

Few considerations:
If you open the popup by window.open() then you also can use:

window.opener.location.reload(true); // Make a new request to the server.
window.opener.location.reload(false); // Attempt from the cache.

If you use window.showModalDialog and self as the second parameter then use:

window.dialogArguments.location.reload(true); // Put before close
OR
window.dialogArguments.location = window.dialogArguments.location;

Using this way you can change the query parameter of parent window/provide a completely a new url. Interesting.........

One another thing sometime you would like To know the parent address due to security issue or To handle multiple opener for a popup, that time you can use window.opener.location.href To validate the parent window.

 

<think>好的,用户问的是在Laravel中如何实现窗口关闭父窗口刷新。这个问题涉及到前端JavaScript和Laravel后端的结合使用。我需要先理清楚用户的需求。用户可能是在开发一个功能,比如弹窗表单提交后,关闭窗口刷新父窗口的数据。 首先,我应该考虑如何检测窗口关闭的事件。因为纯JavaScript本身没有直接监听窗口关闭的事件,但可以通过轮询或者使用window.onbeforeunload事件来间接实现。不过,onbeforeunload在页面刷新或跳转时也会触发,可能会导致父窗口不必要的刷新,所以需要找到更可靠的方法。 然后,想到的是窗口关闭前触发一个回调函数,通知父窗口进行刷新。例如,当窗口的表单提交成功后,在关闭前调用window.opener.location.reload()。这样父窗口就会刷新,但需要确保窗口关闭操作是在提交成功之后,而不是直接关闭。 接下来,可能需要分步骤解释。首先,在父窗口中打开窗口时,使用window.open方法,并保存窗口的引用。然后,在窗口的表单提交后,使用Laravel处理提交,返回成功的响应,接着在窗口的JavaScript中调用window.opener的刷新方法,并关闭自身。 另外,需要考虑到跨域的问题,如果父窗口窗口不在同一个域下,可能会受到浏览器的安全限制。但大多数情况下,Laravel应用可能是在同域下,所以这个问题可能不存在。 然后,用户可能希望具体的代码示例,比如父窗口如何打开窗口窗口如何提交表单,以及提交后如何关闭刷新父窗口。例如,在父窗口中有个按钮,点击后打开窗口窗口提交表单到Laravel的路由,处理完成后返回,并在窗口的JavaScript中执行关闭刷新父窗口的操作。 需要注意的是,如果表单提交失败,应该如何处理错误,避免窗口关闭父窗口刷新。因此,可能需要在窗口的表单提交成功后,才触发刷新关闭操作。例如,使用Ajax提交表单,根据服务器的响应决定是否关闭刷新。 可能还需要提到使用Laravel的CSRF保护,确保表单提交中包含_token字段,或者在Ajax请求中设置合适的headers。 另外,可能有用户会问如何检测窗口是否已经关闭,这时候可能需要使用轮询检查窗口的closed属性,但这种方法可能不够高效,不如在窗口主动触发父窗口刷新更可靠。 总结一下,回答的结构应该是:先介绍基本原理,然后分步骤说明父窗口窗口的代码实现,包括如何打开窗口,提交表单,处理响应,关闭窗口刷新父窗口。同时,给出代码示例,并提醒注意事项,如CSRF保护,错误处理等。</think>在Laravel中实现窗口关闭父窗口刷新,主要通过JavaScript与浏览器窗口交互实现。以下是实现步骤和代码示例: 一、基本原理 1. 父窗口使用`window.open()`打开窗口 2. 窗口通过`window.opener`访问父窗口对象 3.窗口关闭前触发父窗口刷新操作 二、具体实现步骤 1. 父窗口代码(如resources/views/parent.blade.php) ```html <button onclick="openChildWindow()">打开窗口</button> <script> let childWindow = null; function openChildWindow() { childWindow = window.open('/child', '_blank', 'width=600,height=400'); // 轮询检查窗口状态(备选方案) const checkChildClosed = setInterval(() => { if (childWindow.closed) { location.reload(); clearInterval(checkChildClosed); } }, 500); } </script> ``` 2. 窗口代码(如resources/views/child.blade.php) ```html <form id="childForm" onsubmit="handleSubmit(event)"> @csrf <input type="text" name="data"> <button type="submit">提交并关闭</button> </form> <script> function handleSubmit(e) { e.preventDefault(); // 使用Fetch API提交表单 fetch('/submit', { method: 'POST', body: new FormData(e.target) }) .then(response => { if (response.ok) { // 提交成功后刷新父窗口关闭当前窗口 window.opener.location.reload(); window.close(); } }) .catch(error => { console.error('Error:', error); }); } </script> ``` 三、Laravel路由配置(routes/web.php) ```php Route::get('/parent', function () { return view('parent'); }); Route::get('/child', function () { return view('child'); }); Route::post('/submit', function (Request $request) { // 处理表单数据 // $request->input('data'); return response()->json(['success' => true]); })->name('submit.form'); ``` 四、注意事项 1. 安全机制:确保在窗口中使用`window.opener`时,父窗口同源(相同协议/域名/端口) 2. CSRF保护:Laravel表单必须包含`@csrf`指令 3. 错误处理:建议在fetch请求中添加catch处理网络错误 4. 备选方案:当窗口非正常关闭时,父窗口的轮询检查可保证刷新 5. 现代浏览器可能阻止自动关闭窗口,建议用户主动触发关闭操作 五、优化建议 1. 添加加载状态提示 2. 使用异步请求处理表单提交 3.父窗口添加错误回调处理 4. 对于复杂场景,可以考虑使用WebSocket或Server-Sent Events实时更新 这种实现方式适用于以下典型场景: - 弹出表单提交窗口 - 独立图片/文件上传窗口 - 第三方授权回调处理 - 需要隔离的支付处理流程 实际开发中可以根据具体需求选择最适合的窗口通信方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值