【问题标题】:What's the best way to embed constant server-side tags inside javascript code?在 javascript 代码中嵌入常量服务器端标签的最佳方法是什么?
【发布时间】:2009-08-18 16:56:24
【问题描述】:

我有一堆 javascript 函数,它们依赖于一些服务器端常量(例如我的资源文件中的字符串)。在开发它们时,我将 javascript 代码保留在视图标题中,因此我可以在我的 javascript 代码中简单地使用服务器端标签,但现在我想将 javascript 函数移动到一个单独的文件中。

我不能使用常规的 js 文件,因为它不会被服务器解释,使得嵌入的服务器标签毫无用处。我也不想在页面中定义变量,因为这看起来很尴尬且容易出错。

我所做的是创建一个新的 aspx 文件,将 javascript 函数放在那里,并在我的主模板中包含该 aspx 文件而不是常规 js 文件。这似乎有点不正统,但它似乎工作正常。

我的方法有没有我没有考虑到的缺点?还是有更好(不那么晦涩)的方法?

编辑 额外问题:我应该在包含的脚本文件中使用 DOCTYPE 吗?毕竟,脚本文件已经包含在脚本标签中。我试图模仿常规的 js 文件,所以我没有指定任何 DOCTYPE。

【问题讨论】:

    标签: asp.net javascript asp.net-mvc iis


    【解决方案1】:

    文件扩展名,无论是 js、aspx、ashx、bla、foo,都不是那么重要。如果您有服务器端生成的不是特定于页面的 javascript,那么创建一个 ASPX 页面来呈现 javascript 应该没问题。

    我们经常使用 HTTP 处理程序在我们的系统中生成动态 javvascript。我们还确保将响应标头设置为 text/javascript 以让客户端浏览器知道我们正在发回 javascript。

    【讨论】:

    • 感谢您的回答。 doctype 真的有必要吗(见我上面的编辑)?如果是这样,javascript文件的确切语法是什么?我的谷歌研究不是很成功。
    • 从浏览器的角度来看,文档类型确实不是必需的。我们经常使用缓存服务器(例如 akamai)并设置规则来缓存某些内容类型(例如样式表和 javvascripts)更长时间,使用 doc 类型标头允许我们这样做而无需依赖文件名/扩展名。
    【解决方案2】:

    使用视图和 MVC 的模板功能是实现此目的的好方法。它易于维护、易于理解并且可以快速完成工作。唯一真正的技巧是让它提供正确的内容类型。做这样的事情:

        public ActionResult ConfigurationSettings()
        {
            Response.ContentType = "text/javascript";
            return View(Configuration);
        }
    

    实际上为您提供 text/html 内容类型。诀窍是确保你得到最后一个字,将它添加到你的控制器:

        protected override void Execute(System.Web.Routing.RequestContext requestContext)
        {
            base.Execute(requestContext);
            requestContext.HttpContext.Response.ContentType = "text/javascript";
        }
    

    您将获得正确的内容类型; ViewResult 似乎强制它去 text/html。

    【讨论】:

    • 正是我想要的——非常感谢!
    【解决方案3】:

    我们使用ScriptDataBlock control from JsonFx 将变量发送到页面本身。它就像一个字典,其中键是变量名(例如“MyNamespace.myVar”),值是普通 C# 值(包括整个对象)。该控件发出适当的命名空间生成和类型转换为本机 JavaScript 类型。所以从这个意义上说,它最终不会“尴尬”或“容易出错”:

    myDataBlock["MyApp.myVar"] = myObject;
    

    如果您正在处理外部文件,那么通用 .ashx 处理程序可能是您最好的选择。它将比整个 aspx 页面更轻,并为您提供对输出的非常原始的控制。您需要确保将“Content-Type”响应标头设置为“text/javascript”(技术上不正确,但最常见的 MIME 类型),并且对于倾向于不尊重 Content-Type 标头的 Internet Explorer,还将“Content-Disposition”标头设置为“inline;MyScriptName.js”,以便它知道内容的扩展名。

    此外,如果这些确实是“常量”而不是运行时计算的数据,您需要将“Expires”标头设置为某个未来日期,以鼓励浏览器缓存结果。这将进一步减少您的服务器请求。

    编辑:如果您正在创建 JavaScript,则没有 DocType。 DocType 仅用于标记。

    【讨论】:

    • 感谢您的回答,但您的编辑让我感到困惑。我决定按照您的建议使用 asxh 文件,并且只在其中放置 javascript 代码。我应该使用文档类型吗?另外,javascript doctype 的正确语法是什么?我试图用谷歌搜索它,但找不到任何相关信息。
    • 很抱歉造成混淆。 JavaScript 没有 DocType,因为 DocTypes 是一个 SQML​​ 声明,它描述了用于验证标记的 DTD。您的 JavaScript 响应应该只包括脚本,而不是标记(包括脚本标签)。这样,您可以将处理程序作为外部脚本引用,浏览器将下载它,就好像它是一个静态文件一样。
    • Content-Type 是指定 MIME 类型的标头(例如“text/javascript”),而 DocType 是 HTML 页面顶部的标签。也许这就是发生混淆的地方。对于 JavaScript 文件, Content-Type 很好,但 DocType 不适用。
    • 抱歉,让我这么痛苦,但是 ashx 文件在我的场景中究竟有什么帮助?我可以控制内容类型标头,但是如何输出带有解析和替换的服务器端标签的 javascript 代码?从文件加载脚本并通过 ProcessRequest 中的 context.Response.Write 写入它不会替换标签。
    • 有趣,所以您使用标记进行替换? .ashx 没有用于构建脚本的设计器界面。当我做这些事情时,我使用格式化字符串并通过{0} 进行替换。无论哪种方式,在发出"<%= this.fooString %>" 之类的内容时,您都必须小心正确地对字符串等进行编码。我还使用 JsonFx(JSON 序列化程序的扩展)中的 EcmaScriptWriter 将字符串、日期、对象、数组等正确编码为 JavaScript 文字。它更安全,您永远不必担心多余的引号字符会搞砸。
    【解决方案4】:

    您正在使用 MVC 框架(您的问题被标记为这样)对吗?如果是这样,您可以创建一个返回 JavaScriptResult 的操作,该操作将在页面加载时执行:

    public class JSController : Controller {
        public ActionResult Headers() {
            // create your variables here
            return JavaScript("alert('hi');");
        }
    }
    

    然后你可以将它添加到你的 aspx/master 页面:

    <script src="/JS/Headers" type="text/javascript"></script>
    

    【讨论】:

    • 您对我使用的平台是正确的。我假设您的意思是从 js 文件加载脚本,然后将其作为 Javascript 结果返回(将脚本作为字符串嵌入到控制器代码中会非常难看,有 10 多个 javascript 函数......)。不幸的是,除非我按字符串构建脚本字符串并手动插入服务器端常量,否则这在我的场景中不起作用。问题是 Javascript 结果不是由服务器解释,而只是通过适当的响应头传递给浏览器。
    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2018-07-08
    • 2010-09-10
    • 2011-03-05
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多