Node.js应用res.render无报错不渲染EJS,返回页面JS无法调用问题
问题原因
- 核心触发原因:浏览器出于安全策略限制,不会执行通过
innerHTML属性插入的<script>标签内容。你通过XMLHttpRequest请求拿到newform.ejs渲染的完整HTML代码后,直接替换整个<html>节点的内容,此时页面里引入的外部JS资源、内联JS代码都不会被浏览器解析执行,自然无法调用对应函数。 - 额外排查点:检查
newform.ejs中引入JS的路径是否正确,你在app.js中配置了app.use(express.static(__dirname)),根目录下的javascript.js的引入路径应该写绝对路径/javascript.js,避免使用相对路径导致路由层级变化时资源加载失败。
解决方案
方案1(最推荐,无额外兼容问题):改为直接页面跳转
你本次发起的是普通GET请求,没有异步局部加载的需求的话,直接把createNew的逻辑改成页面跳转即可,浏览器会正常加载解析整个新页面的所有资源:
function createNew() { window.location.href = '/createnew' }
方案2(需保留异步加载逻辑时使用):手动执行插入的JS代码
如果你必须保留AJAX异步替换页面的逻辑,在替换innerHTML之后,手动提取页面中所有的script标签,重新创建script元素插入页面触发执行:
function createNew() { let getUrl = window.location; let baseUrl = getUrl.protocol + "//" + getUrl.host; let query = baseUrl + '/createnew?' let req = new XMLHttpRequest() req.open("GET", query, true) req.addEventListener('load', function () { let response = req.responseText document.querySelector("html").innerHTML = response // 手动执行所有新插入的script代码 Array.from(document.querySelectorAll('script')).forEach(oldScript => { const newScript = document.createElement('script') // 复制原有script的所有属性 Array.from(oldScript.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value)) // 复制内联script的代码内容 newScript.textContent = oldScript.textContent oldScript.parentNode.replaceChild(newScript, oldScript) }) }) req.send() }
注意:如果
newform.ejs和profilelist.ejs引入了相同的全局JS文件,异步替换后可能会出现变量重复声明、事件重复绑定的问题,建议公共JS资源统一放到公共模板中仅加载一次。
内容的提问来源于stack exchange,提问作者Taylor Googe
相关产品推荐
相关产品推荐

