DNN主题用2sxc IRenderService嵌入App时JS报错如何解决
2sxc嵌入DNN主题后webApi调用"Can't find page"报错解决
问题场景
尝试将2sxc应用嵌入DNN主题布局页面,模块HTML可以正常渲染,使用的服务端代码如下:
<%-- This namespace provides this.GetScopedService<T>() --%> <%@ Import Namespace="ToSic.Sxc.Dnn" %> <%-- This namespace provides all the common 2sxc services --%> <%@ Import Namespace="ToSic.Sxc.Services" %> <%= this.GetScopedService<IRenderService>().Module(1041,3421) %>
但前端JavaScript运行异常,应用内自定义搜索功能的前端逻辑代码如下:
// get the sxc-controller for this module var sxc = $2sxc(3421); // now get the data in the promise sxc.webApi.get('app/auto/api/Forms/SearchForm') .then(data => { console.log(data) });
最初代码运行提示$2sxc未识别,手动在布局页添加如下脚本引用后该报错消失:
<script src="/desktopmodules/tosic_sexycontent/js/2sxc.api.min.js" type="text/javascript"></script>
但后续调用sxc.webApi.get方法时抛出错误:
Uncaught Can't find page - something went wrong, pls contact 2sxc.org
尝试额外引入如下脚本后问题反而加重:
<script src="/desktopmodules/tosic_sexycontent/dist/inpage/inpage.min.js" type="text/javascript"></script>
根本原因
手动硬编码引入2sxc静态JS文件的做法完全错误。仅调用IRenderService.Module()只会输出模块本身的HTML内容,不会自动注入2sxc前端运行必需的页面上下文元数据、路由配置和基础资源,webApi拿不到当前模块、页面的匹配信息就会抛出"Can't find page"错误。手动引入的inpage.min.js是编辑模式专用的内页编辑脚本,普通匿名浏览场景引入后会触发编辑权限、编辑状态相关的校验逻辑,反而会导致更多报错。
正确解决方法
不要手动引入任何2sxc的静态JS文件,在渲染模块前调用2sxc页面服务,自动注入运行所需的上下文、基础资源即可,修改后的服务端代码如下:
<%-- 引入所需命名空间 --%> <%@ Import Namespace="ToSic.Sxc.Dnn" %> <%@ Import Namespace="ToSic.Sxc.Services" %> <% // 获取页面服务,用于自动注入必需的JS、上下文meta标签 var pageSvc = this.GetScopedService<IPageService>(); // 激活自动资源注入,会自动输出2sxc运行需要的基础脚本、上下文到页面对应位置 pageSvc.Activate(); %> <%-- 渲染目标模块 --%> <%= this.GetScopedService<IRenderService>().Module(1041,3421) %>
额外注意点
- 不要手动添加任何
<script>标签引入2sxc的静态JS文件,IPageService.Activate()会自动识别当前页面是浏览/编辑模式,加载对应所需的最小资源集,不会引入冗余脚本 - 渲染模块的代码必须放在页面
<form runat="server">标签内部,不能放在form标签外,否则DNN的页面请求上下文无法正常传递 - 如果主题使用自定义脚本加载逻辑,不要给2sxc自动注入的脚本加
async/defer属性,避免出现$2sxc未定义的加载时序错误
内容的提问来源于stack exchange,提问作者Dieter V
相关产品推荐
相关产品推荐

