【问题标题】:How can I include an external javascript file that contains coldfusion code?如何包含包含冷融合代码的外部 javascript 文件?
【发布时间】:2011-07-05 15:47:26
【问题描述】:

我有一些使用完全相同的 JavaScript 代码的冷融合文件。我想将 javascript 分离成一个 .js 文件并将其包含在每个文件中,这样我就不必多次重复所有内容。因此,我将 javascript 代码分成了一个名为“myPage.js”的文件,并在“myPage.cfm”中包含了一个脚本标签 -

<script language="javascript" src="myPage.js"></script>

问题是在使用&lt;cfoutput&gt;s 等注入值的javascript 中传播了一些coldfusion 代码,并且不再正确翻译,可能是因为它试图将其作为纯javascript 读取。有什么办法可以让我拥有一个外部 js 文件,但表明我希望它也使用冷融合来解释它?

我发现的一种解决方法是将javascript放入一个coldfusion文件而不是一个名为“myPageJavascript.cfm”的javascript文件中,将所有javascript代码包围在&lt;script type="text/javascript"&gt;标签中,然后使用cfinclude在所有页面中包含该 javascript。这很好用,但在我看来它不像包含 js 文件那样直观......这种情况的标准做法是什么?有什么方法可以将它实现为外部 js 文件,还是我应该坚持使用我的 Coldfusion 模板文件?

【问题讨论】:

    标签: javascript coldfusion script-tag


    【解决方案1】:

    为了识别来自服务器的内容,并让 CF 函数 toScript 正确呈现变量,包括结构和数组,我使用以下方法:

    <script>
        var cf = {};
        <cfscript>
            writeOutput(toScript(application.applicationname,'cf.app'));
            writeOutput(toScript(cgi.remote_addr,'cf.url'));
        </cfscript>
    </script>
    

    呈现给:

    <script>
        var cf = {};
        cf.app="Lucee";cf.url="149.79.80.135";
    </script>
    

    现在在您的外部 .js 中,您只需使用 cf.app、cf.url ... 等等。

    有时在帖子的 get 或 FORM 结构上传递 URL 结构会非常方便。

    【讨论】:

      【解决方案2】:

      其他答案更优雅高效,但简单的方法是将文件扩展名从 .js 更改为 .cfm,如下所示:

      <script language="javascript" src="myPage.cfm?id=#createUuid()#"></script>
      

      createUuid() 用于防止缓存,假设文件输出会有所不同,很可能基于来自session 范围的变量。客户端将其作为 JavaScript 加载,而服务器将其作为 ColdFusion 处理。你也可以对样式表做同样的事情。

      现在,如果您的 JavaScript 依赖于调用页面中的值,您可以在 URL 上传递它们:

      <script language="javascript" src="myPage.cfm?name1=value1&name2=value2"></script>
      

      在这种情况下,您实际上可以可以在传递相同的 URL 参数时利用缓存。

      总体而言,与重构代码以保持.js 文件“纯”相比,这种方法的工作量要少得多,同时预先在&lt;script/&gt; 块中输出它所依赖的变量。

      【讨论】:

      • 另外,我建议将此标头包含在 .cfm 中:&lt;cfheader name="Content-Type" value="application/x-javascript; charset=utf-8"&gt;
      • @Sergii:&lt;cfcontent&gt; 我同意这是正确的做法,但在这种情况下有什么优势?我假设客户端将始终将 &lt;script/&gt; 标记中引用的内容视为这样,而不需要 http 标头来做正确的事情。
      • 我现在记不太清了,但我想我在一些没有正确标题的浏览器接受这种基于 CFML 的脚本时遇到了问题。
      • @Sergii:有趣,如果你还记得,我很想知道客户是什么。
      【解决方案3】:

      我最初喜欢 @Orangepips 对 @Anooj 的回答的原因在于,每次您在 CFM 中包含 &lt;script&gt; 时都需要单独的 Javascript 块,因此更便于未来维护。

      然而,经过几分钟的思考,结合这两个答案很容易消除这种情况。这为您提供了模块化,以便您寻求今天的开发和未来的维护 - PLUS 作为最佳实践,可以为您提供静态 Javascript 的隔离和缓存,以降低您的 CF 页面请求大小和响应速度。

      基本上,您应该创建一个基于 CF 的外观,您将在每次需要 Javascript 功能时包含或调用该外观。在我的示例中,我将外观设置为一个可调用函数,您可以将 JS 参数传递给该函数(正如 @Orangepips 所暗示的那样),以便严格控制传递给 JS 的变量。

      (顺便说一句,作为最佳实践,我倾向于将所有内联 JS 放入变量中,然后将其填充到 CFHEADER 中,以确保它位于页眉中。)

      dosomething.js

      <script type='text/javascript'>
          <!-- assert vars were passed in -->
          if ( source == undefined )
               alert("Developer error: source not defined.");
               return;
          }
          if ( urlpath == undefined )
               alert("Developer error: urlpath not defined.");
               return;
          }
      
          <!-- do some js stuff --->
          alert('source: ' + source + ", urlpath: " + urlpath );
      </script>
      

      udf.cfm:

      <cffunction name="doSomething" output="true" returntype="void">
          <cfargument name="source" required="true" /> 
          <cfargument name="urlpath" required="true" /> 
      
          <cfsavecontent variable="header">
          <script type="text/javascript">
              <!-- var init -->
              <cfoutput>
                  var source = '#arguments.source#';
                  var urlpath = '#arguments.urlpath#';
              </cfoutput>
          </script>
          <script language="JavaScript" type="text/javascript" src="dosomething.js"></script>
          </cfsavecontent>
          <cfhtmlhead text="#header#">
      </cffunction>
      

      应用程序.cfm

      <cfinclude template="udf.cfm">
      

      view1.cfm:

      <cfoutput>#doSomething("view 1", "http://myurl/view1")#</cfoutput>
      

      view2.cfm:

      <cfoutput>#doSomething("view 2", "http://myurl/view2")#</cfoutput>
      

      将代码分离出来后,任何未来的变化都会变得更容易(JS 与 JS-var 分离,定义外观与调用它的各个视图分离)。例如。在添加变量时,您可以使其向后兼容,以便所有现有视图继续工作。

      udf.cfm 更改:

      <cfargument name="newVar" required="false" default="" /> 
      <cfif len(arguments.newVar)>
      var newVar = "#arguments.newVar#";
      </cfif>
      

      dosomething.js 更改:

      // keep JS backwards compatible
      if ( newVar != undefined) {
          // new var was passed in, do something with it
      }
      // else, not passed in 
      

      【讨论】:

        【解决方案4】:

        我建议您在 js 包含之前创建一个脚本块,其中包含要在包含 js 文件中使用的所有变量。在您的情况下,将您放在 js 文件中的那些 cfoutput 变量移动到主文件

            <script type='text/javascript'>
            var sourceName = <cfoutput>#Application.name#</cfoutput>
            </script>
        
            <script src="js/myPage.js" type="text/javascript"/>
        

        在 myPage.js 文件中,您可以使用变量 sourceName,它具有来自 Coldfusion 变量的实际值。从而帮助您将coldfusion代码和js代码分开。

        如果您有很多变量要移出,请考虑创建对象类型变量并将所有这些变量添加到其中。

        注意:添加带有 script 标签的 js 将有助于它缓存并提高页面性能。所以不要将js文件加载为cfm文件

        【讨论】:

        • +1 表示最正确的方法。也就是说,我相信客户端还会缓存从&lt;script/&gt; 标记的src 属性引用的.cfm 或任何扩展名文件。
        • 这是我一直使用的方法,1 段代码,其中所有变量/数据由冷融合填充,以及一个包含所有函数的单独 js 文件。
        • 我同意给出答案的“纯度”(将 .js 文件保留为纯 JS)......但是将 JS 代码卸载到单独的文件的目的是为了模块化(导致易于未来维护)。在每个
        【解决方案5】:

        如果您将 ColdFusion 代码移回您获取它的位置,您将使用它来设置一些 JavaScript 变量,并且只保留纯 JavaScript,然后在您的外部 JavaScript 文件中使用这些变量,那么效率会更高。这将是最简单的解决方案。更高级的方法是在外部 JavaScript 文件中定义函数,这些函数将从 ColdFusion 生成的 HTML 中的脚本标签调用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-09-10
          • 2020-09-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-01
          • 1970-01-01
          相关资源
          最近更新 更多