You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态生成嵌入iframe的<script>标签函数无法调用问题求助

问题原因

当你通过contentWindow.document.body.innerHTML = data将HTML内容插入iframe时,浏览器不会自动执行其中的<script>标签——这是浏览器的安全机制,避免innerHTML注入的脚本被意外执行。即使脚本标签存在于DOM中,也不会被解析执行,这就是为什么手动在控制台输入函数能运行,但点击按钮找不到函数的原因。另外你拼接的脚本里还有语法错误:var url = updateRecorderInfoServlet?RecorderID=' + RecorderID缺少开头的单引号和结尾的分号,会导致脚本本身就无法运行。

解决方案

下面提供几种可行的解决办法,按推荐程度排序:

方案1:直接在按钮的onclick中写逻辑,无需定义函数

不用提前定义sendRequest函数,直接把跳转逻辑写在按钮的onclick属性里,完全避开脚本执行的问题:

htmlContent.append(String.format("<td><button type='button' onclick=\"window.location.href='updateRecorderInfoServlet?RecorderID=%s'\">%s</button></td>", recorderId, recorderId));

点击按钮时直接触发跳转,简单可靠,不需要依赖iframe里的脚本函数。

方案2:更新iframe内容后手动执行脚本

如果一定要保留函数定义的写法,在通过innerHTML插入内容后,需要手动提取并执行iframe中的脚本。修改JSP里的submitForm函数:

function submitForm() {
  var formData = new FormData(document.getElementById('displayForm'));

  fetch('getRecorderInfoServlet', {
    method: 'POST',
    headers: { 'Content-Type': 'text/plain' },
    body: formData.get('Recorder_ID')
  })
  .then(response => response.text())
  .then(data => {
    const iframe = document.getElementById('resultFrame');
    const iframeDoc = iframe.contentWindow.document;
    // 设置iframe内容
    iframeDoc.body.innerHTML = data;
    // 提取并执行所有script标签
    const scripts = iframeDoc.body.querySelectorAll('script');
    scripts.forEach(oldScript => {
      const newScript = document.createElement('script');
      newScript.textContent = oldScript.textContent;
      iframeDoc.head.appendChild(newScript);
      oldScript.remove();
    });
  })
 .catch(error => console.error('Error:', error));
}

同时修正Servlet里脚本的语法错误:

htmlContent.append("<script>");
htmlContent.append("function sendRequest(RecorderID) {");
htmlContent.append("  var url = 'updateRecorderInfoServlet?RecorderID=' + RecorderID;"); // 补全单引号和分号
htmlContent.append("  console.log('Request URL:', url);");
htmlContent.append("  window.location.href = url;");
htmlContent.append("}");
htmlContent.append("</script>");

方案3:让Servlet返回完整HTML页面,设置iframe的src

这是最规范的做法:让getRecorderInfoServlet返回完整的HTML文档(包含<html>、<head>、<body>标签),然后在JSP里通过设置iframe的src属性加载内容,而非用innerHTML插入。

修改Servlet的响应:

response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<script>");
out.println("function sendRequest(RecorderID) {");
out.println("  var url = 'updateRecorderInfoServlet?RecorderID=' + RecorderID;");
out.println("  console.log('Request URL:', url);");
out.println("  window.location.href = url;");
out.println("}");
out.println("</script>");
out.println("</head>");
out.println("<body>");
// 拼接表格内容
out.println("<table>");
out.println(String.format("<tr><td><button type='button' onclick=\"sendRequest('%s')\">%s</button></td></tr>", recorderId, recorderId));
out.println("</table>");
out.println("</body>");
out.println("</html>");

修改JSP里的submitForm函数,直接设置iframe的src:

function submitForm() {
  const recorderId = document.getElementById('recorderId').value;
  // 用GET方式传递参数,自动编码避免特殊字符问题
  document.getElementById('resultFrame').src = `getRecorderInfoServlet?Recorder_ID=${encodeURIComponent(recorderId)}`;
}

同时调整Servlet的doGet方法处理参数(如果之前用的是doPost),这样浏览器会正常解析iframe中的HTML和脚本,函数能被正常调用。

内容的提问来源于stack exchange,提问作者DamanS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 17:40:58