在.cshtml文件的if语句中访问Script外JavaScript变量求助
解决.cshtml中Razor语句访问JavaScript变量的问题
嘿,这个问题其实是个很典型的服务器端与客户端执行时机冲突的坑,我来给你捋清楚:
首先得明确:你的@if (!Model.oldLayout && preloadSupported)是Razor服务器端代码,它在页面被发送到用户浏览器之前就已经执行完毕了;而preloadSupported这个JS函数是客户端浏览器代码,只有当页面加载到浏览器里才会运行。服务器根本看不到客户端的JS变量/函数,所以直接在Razor的if里引用肯定会报错或者完全不生效。
最靠谱的解决方案:把判断逻辑移到客户端JS里
既然preloadSupported是检测浏览器特性的,本来就该在客户端处理,我们可以直接用JS动态创建preload标签,同时把服务器端的Model.oldLayout值传递到JS里:
<html> <head> </head> <body> <script> const preloadSupported = () => { const link = document.createElement('link'); const relList = link.relList; if (!relList || !relList.supports) return false; return relList.supports('preload'); }; // 把服务器端的Model.oldLayout渲染成JS布尔值,再结合客户端特性检测 if (!@Model.oldLayout && preloadSupported()) { const preloadLink = document.createElement('link'); preloadLink.rel = 'preload'; preloadLink.href = 'staticResource.js'; preloadLink.as = 'script'; // 按需添加其他属性,比如 crossorigin="anonymous" document.head.appendChild(preloadLink); } </script> </body> </html>
为什么原来的写法行不通?
简单说:服务器在生成HTML的时候,会把Razor代码翻译成静态HTML输出,但它完全不认识你的JS函数preloadSupported——对服务器来说,这个名字就是个未定义的标识符,自然没法进行判断。只有当页面到了浏览器里,JS代码才会被解析执行,这时候服务器早就完成它的工作了。
不推荐的方案(仅作了解)
如果硬要在服务器端输出preload标签,你只能通过解析客户端的User-Agent头来推断浏览器是否支持preload,但这种方式非常不可靠:User-Agent可以伪造,而且浏览器版本更新快,需要不断维护规则,完全没必要舍近求远。
内容的提问来源于stack exchange,提问作者AlreadyLost
相关产品推荐
相关产品推荐

