首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Frameset 框架頁面整體與局部刷新解決方案:JavaScript 跨框架操作實戰

     編輯:Java 程式設計入門

Frameset 架構基礎結構


<frameset cols="280,*" frameborder="yes" bordercolor="silver">
    <frame src="menuAction!showTree" name="menuTree" id="leftTree" scrolling="no">
    <frame src="content.jsp" name="main" id="showContent" scrolling="auto">
</frameset>
  • leftTree (左側):功能選單樹,需動態更新
  • showContent (右側):內容展示區,表單提交、列表操作

場景一:右側提交後整體刷新左側框架

問題

右側框架提交表單 (Struts2 Action) 後,需重新載入左側選單反映最新權限/結構。直接返回主頁面會導致巢狀 Frameset。

解決方案:JavaScript 跨框架重載


// 右側頁面 content.jsp - body onload
function init() {
    // 方式 1:直接 reload (最簡單)
    window.parent.frames["leftTree"].location.reload();

    // 方式 2:指定新 URL (可帶參數)
    // window.parent.frames["leftTree"].location.href = "menuAction!showTree?timestamp=" + Date.now();
}
<body onload="init()">

Struts2 Action 返回配置


<action name="saveContent" class="com.action.ContentAction" method="save">
    <result name="success">/content.jsp</result> 
    <!-- 返回右側頁面,由頁面 onload 觸發左側刷新 -->
</action>

場景二:右側提交後局部刷新左側特定元素 (AJAX)

需求

不重載整個左側頁面,僅更新選單中某個 <div id="node-123"> 區塊。

原生 JavaScript AJAX 實作


// 右側頁面提交成功後呼叫
function refreshLeftTreeNode(nodeId) {
    var xhr = createXHR();
    var url = "menuAction!getNodeHtml?nodeId=" + nodeId; // 返回 HTML 片段

    xhr.open("GET", url, true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                // 關鍵:跨框架存取 DOM 並更新
                var leftDoc = window.parent.frames["leftTree"].document;
                var target = leftDoc.getElementById(nodeId);
                if (target) {
                    target.innerHTML = xhr.responseText;
                } else {
                    console.warn("左側框架找不到元素: " + nodeId);
                }
            } else {
                alert("刷新失敗: " + xhr.status);
            }
        }
    };
    xhr.send(null);
}

// 建立跨瀏覽器 XHR
function createXHR() {
    if (window.XMLHttpRequest) return new XMLHttpRequest();
    try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
    throw new Error("不支援 AJAX");
}

後端 Action 返回片段


public String getNodeHtml() {
    HttpServletResponse response = ServletActionContext.getResponse();
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.print(menuService.buildNodeHtml(nodeId)); // 返回 <li>...</li> 片段
    return null; // 不走 result
}

跨框架存取核心 API 總覽

操作語法說明
取得父視窗window.parentFrameset 頁面的 window 物件
取得同級框架window.parent.frames["frameName"] 或 window.parent.frames[0]由 name 或 index 存取
取得框架 documentwindow.parent.frames["name"].document操作目標框架 DOM
重載框架frames["name"].location.reload()保留 POST 資料會提示確認
導向新 URLframes["name"].location.href = url乾淨導向、可帶查詢參數
呼叫框架函式frames["name"].functionName()跨框架函式調用

同源策略限制與解決

⚠️ 同源策略阻擋跨域存取

若 Frameset 與子框架域名、協定、埠口不一致,window.parent.frames["x"].document 會拋出 SecurityError。

解決方案

  1. 同域部署:確保所有框架同源 (生產環境標準做法)
  2. document.domain = "example.com":僅限主域相同、子域不同 (如 a.example.com / b.example.com)
  3. postMessage API:現代跨域通訊標準,雙向安全通訊

現代化替代方案建議

方案優點遷移建議
iframe + postMessage保留框架隔離、解決跨域、安全可控逐步替換 frame 為 iframe
單頁應用 (Vue/React + Router)無框架問題、體驗流暢、SEO 需 SSR重寫前端、API 化後端
AJAX 區塊更新 (jQuery/Fetch)輕量、無框架、漸進增強針對局部刷新場景直接改造

總結

Frameset 跨框架操作核心在於 window.parent.frames["name"] 存取目標框架 window/document/location 物件。整體刷新用 location.reload() 或 location.href,局部刷新用 AJAX 取得片段後注入 innerHTML。實務上務必處理同源策略、元素不存在、載入失敗等異常情況。新專案強烈建議採用現代前端架構替代 Frameset,存量系統可用本文方案維護延展。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved