以前的同事問了我一個問題:
在 A 視窗 (list.asp) 中會用 window.open 開啟子視窗 B (edit.asp) ,然後 B 視窗上的表單資料會 submit 到一支 C 程式 (save.asp) 。
而 當 C 程式做完存檔動作後,在最後面程式碼裡加上了:
1
2
3
4
5
6
7
| <script type="text/javascript">
<!--
alert('存檔成功!');
window.opener.location.reload();
window.close();
//-->
</script>
|
理論上 A 視窗會重新整理,然後子視窗 B 會關掉;但是現在 A 視窗會出現以下訊息 (IE) :

或是在 Firefox 中出現:

這個問題只看字面的話,說實在的有點難懂,我想我用以下程式來說明好了:
註:這裡舉的例子比較簡單,沒有考慮到實用上的完整性,大家在實作時請自行小心。
list.asp
1
2
3
4
5
6
7
8
9
| <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<title>列表頁</title>
</head>
<body>
<a href="edit.asp" onclick="window.open('edit.asp', 'b', 'width=100,height=100'); return false;">測試</a>
</body>
</html>
|
edit.asp
1
2
3
4
5
6
7
8
9
10
11
| <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<title>表單</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="save.asp">
<input type="submit" name="Submit" value="送出" />
</form>
</body>
</html>
|
save.asp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<title>處理頁</title>
</head>
<body>
<script type="text/javascript">
<!--
alert('存檔成功.');
<strong>window.opener.location.reload();</strong>
window.close();
//-->
</script>
</body>
</html>
|
如果大家直接執行 list.asp 並按下「測試」連結,在出現表單視窗後按下「送出」,可能會發現沒有我朋友所說的問題。

那為什麼我朋友會遇到呢?
其實在 Firefox 的訊息視窗裡可以看出一些端倪,原因就在 POSTDATA !怎麼說呢?如果我把 list.asp 改成以下這樣:
1
2
3
4
5
6
7
8
9
10
11
12
| <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<title>列表頁</title>
</head>
<body>
<a href="edit.asp" onclick="window.open('edit.asp', 'b', 'width=100,height=100'); return false;">測試</a>
<strong><form id="form1" name="form1" method="post" action="list.asp">
<input type="submit" name="Submit" value="送出" />
</form></strong>
</body>
</html>
|
這時我們先按下 list.asp 的「送出」,也就是說 list.asp 會把資料 POST 給自己 (當然如果是從別的頁面 POST 過來的也是一樣) ,然後再執行一次剛剛的表單測試:
這時畫面就會跳出:

也就是說 list.asp 必須重新把 POST 的資料再次載入。
那麼如何解決呢?兩個方法可用:
- list.asp 的表單改用 GET 來傳遞參數。
- 非得用 POST 的話,那 save.asp 就不要用 location.reload() ,而改用 location.replace() 。
location.replace() 怎麼用呢?範例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<title>處理頁</title>
</head>
<body>
<script type="text/javascript">
<!--
alert('存檔成功.');
<strong>window.opener.location.replace('list.asp');</strong>
window.close();
//-->
</script>
</body>
</html>
|
這樣 list.asp 就會被重新讀取了。