我想向Javascript发送ColdFusion结构。在查看我如何做到这一点时,我找到了cfwddx标签。它似乎让我在那里中途。我创建了一个测试程序
<head>
<script type = "text/javascript" src = "frag3.js"> </script>
</head>
<body>
<cfset str = StructNew()>
<cfset str['betty'] = 1>
<cfset str['nancy'] = 2>
<cfdump var = "#str#">
<cfwddx action="CFML2JS"
input="#str#"
toplevelvariable="xyz"
output = "genstr">
<cfoutput>
<script type = "text/Javascript">
test('betty')
function test (arg) {
alert("got to test");
#genstr#
alert ("xyz " + xyz[arg]);
}
nothing()
</script>
</cfoutput>
cfdump给出了正确的答案
当我查看#genstr#的输出时,它包含正确的javascript代码:
xyz = new Object(); xyz["betty"] = "1"; xyz["nancy"] = "2";
当我如上所示运行内联代码时,警报会给出正确的答案。当我调用&#34;没什么()&#34;函数,驻留在frag3.js上,一个警告显示它已运行,因此src语句正在运行。
但是,当我将函数测试(arg)本身移动到frag3.js时,它不会运行。
任何人都可以告诉我如何获得&#34;测试&#34;作为外部函数工作,而不只是在我的ColdFusion代码中内联?顺便说一句,我还没有学过jquery,所以jquery的答案无济于事;我需要基本的javascript。
答案 0 :(得分:1)
而不是写变量位(让他们称之为&#34;初始化&#34; 或&#34;配置&#34; )你的网站的源代码(或者更糟糕的是,你的静态JS文件的源代码),我推荐以下内容。
创建一个具有远程可调用方法的组件,该方法返回具有所有配置的结构。您现在可以从服务器上的ColdFusion代码(您将收到一个结构)调用该方法,并通过Ajax从客户端上的JavaScript代码(您将收到JSON)调用该方法。
/** Config.cfc (or call it something similar)
*
*/
component {
remote struct function getConfig() returnformat="JSON" {
var str = StructNew();
str['betty'] = 1;
str['nancy'] = 2;
return str;
}
}
你的main.cfm(为了简化示例,我包含用于处理Ajax请求的jQuery):
<html>
<head>
<script type="text/javascript" src="frag3.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<h1>Config, as seen by the server</h1>
<cfinvoke component="Config" method="getConfig" returnvariable="cfg">
<cfdump var="#cfg#">
<h1>Config, as seen by the client</h1>
<pre id="cfgDump"></pre>
<script type="text/javascript">
$(function () {
$.get("Config.cfc?method=getConfig").done(function (cfg) {
// cfg already is a regular JS object at this point
// convert to JSON again for display purposes
$("#cfgDump").text( JSON.serialize(cfg, null, 2) );
});
});
</script>
</body>
</html>
清洁简单。
答案 1 :(得分:0)
对您的问题最有效的解决方案可能是在文档本身中包含内联的动态内容。
将函数test(arg)
复制到Javascript文件时,我想您也在复制#genstr#
?所以它在js文件中看起来与你上面完全一样?
这是按预期工作的。 .js文件不处理冷融合,如果你看看你的开发者控制台,你可能会收到语法错误。
您可以将其保留为文档内联,也可以将js文件的扩展名更改为.cfm。
此时,您的js_main.cfm
(示例)文件将被视为任何其他浏览器请求的文件,如果您的请求处理执行此操作,它将删除页眉和页脚,因此会导致更多错误。您需要保护这些文件。您可以使用应用程序文件中的某些cfif来执行此操作,例如
<!--- This checks the path to make sure it doesn't contain livemedia. --->
<cfif not listfind(cgi.script_name,"livemedia","/")>
... do includes
</cfif>
或者你可以这样做,并将这些文件锁定在一个文件夹中,只是为了服务JS,带有cfm扩展名的CSS文件和自己的application.cfc / cfm来覆盖网站的全局文件,如果遇到这种情况我觉得动态geerated js / css确实是最好的选择。
然后,如果确实需要,您可以在OP中显示并将变量转发到客户端。或者,您可以将两个“应用程序”命名为相同,虽然这样可以使数据共享变得非常简单,但我仍然建议您小心分享内容并公开并确保正确保护子应用程序。
是的,正如其他人所说,#SerializeJSON()#
是将服务器端变量/对象复制到客户端的现代方法。
例如..
<cfset CFStruct = {big = "little", red = "blue", subArray = ["A","B","C","D"]} />
<script>
<cfoutput>JSObj = #SerializeJSON(CFStruct)#;</cfoutput>
</script>
<!--- While I use shorthand to form the struct and subArray, that's only for speed,
structs, arrays, queries, etc formed in any fashion work just fine. --->
使用元素JSObj
(具有子元素big, red, subArray
)创建A, B, C, D
。
但是,无论您选择哪种方法(wddx
或SerializeJSON()
),这些方法都无法在.js文件中使用。
我必须提到允许服务器解析.js文件的另一个选项是存在,但这会比它的价值更加痛苦。您使用普通js文件的许多情况都会受到干扰。
请注意,通过<script>
和<link>
等客户端标记调用的文件是完全独立的请求。他们不会共享url, form, request, variables
范围。但是,如果两个应用程序具有相同的名称,他们可以共享cookies
和client
以及session
范围。
最后,通过html标签调用的外部内容的精彩之处在于,无论扩展名如何,它通常都是默认缓存的。这对于带宽甚至是加载页面的速度非常有用,直到您有一个想要一致地加载非缓存副本的场景。
因此,当您觉得必须动态生成想要粘贴在外部文件中的内容时,您可以使用几种方法。
<script src="/livemedia/js_main.cfm?randomizer=#randrange(1,1000000)#"></script>
<script src="/livemedia/js_main.cfm?#session.username#"></script>
如果要将某些内容附加到javascript文件的查询字符串中,则应将该文件的静态内容移动到每次不需要重新生成的单独文件中。没有必要为每个页面请求重新加载15个javascript函数,因为1包含动态内容。
答案 2 :(得分:-1)
我不是一个大的CF开发人员,但我知道输出结构和数组以供javascript使用的最简单方法是使用SerializeJson()
例如,作为CF页面中的JS变量:
<script>
var myVar = <cfoutput>#SerializeJson(str)#</cfoutput>;
</script>
虽然JSON是一个字符串...当它在脚本标记内打印时,javascript会将其作为数组或对象读取,而无需在客户端中解析它。
我也使用完全相同的输出进行ajax传送