The most effective solution to your problem is probably going to be including the dynamic content inline in the document itself.
When you copy the function test(arg)
to the Javascript file, I suppose you're copying #genstr#
as well? So it looks, in the js file, exactly as you have it above?
This is working as intended. .js files do not process cold fusion, and if you look at your developer console, you're probably getting a syntax error.
You can either keep it inline to the document, or change the extension of the js file to .cfm.
At this point, your js_main.cfm
(example) file will be treated like any other browser-requested file, and it will drop headers and footers in if your request processing does that, so it will cause more errors. You need to protect these files from that. You can either do this with some cfifs in your application file like
<!--- This checks the path to make sure it doesn't contain livemedia. --->
<cfif not listfind(cgi.script_name,"livemedia","/")>
... do includes
</cfif>
Or you can do like I would probably do and lock these files in a folder just for serving JS, CSS files with cfm extension with their own application.cfc/cfm to override the site's global file, if I ran into a situation where I felt that a dynamically geerated js/css was truly the best option.
You can then do as you show in your OP and relay variables to the client side if you really need to. Alternatively, you can name the two "applications" the same, and while that makes data sharing really easy, I should still advise that you be careful what you share and you expose and making sure to properly secure the sub-application.
And yes, as others have suggested, #SerializeJSON()#
is the modern approach to copying a server-side variable/object to the client side.
For instance..
<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. --->
Creates JSObj
with the elements big, red, subArray
(which has the child elements A, B, C, D
).
Still, no matter which method you choose (wddx
or SerializeJSON()
), these will not work in a .js file.
I must mention that the other option of allowing the server to parse .js files is there but this would be a lot more pain than it is worth. The many occasions where you'd use a plain js file would be interfered with.
Note that your files called via client side tags like <script>
and <link>
are entirely seperate requests. They will not share the url, form, request, variables
scopes. However they can share cookies
and client
and session
scope if the two applications have the same name.
Lastly the wonderful thing about external content called via html tags, regardless of extension, is that it's usually cached by default. This is wonderful for bandwidth and even for speed loading the pages, until you have a scenario where you want to load a non cached-copy consistently.
For this reason, when you feel like you have to dynamically generate something that you want to stick in an external file, you have a few methods.
- You can set no-cache in the header (CF or Htaccess can do this).
- You can provide toss a random number in the query string of the script call.
<script src="/livemedia/js_main.cfm?randomizer=#randrange(1,1000000)#"></script>
- Perhaps the file doesn't need refreshed every time for every user, maybe simply that each user needs to see a different copy. You would still attach a query string because multiple users may log in from the same computer. It, however, would be user specific.
<script src="/livemedia/js_main.cfm?#session.username#"></script>
- Reconsider how your page compiles and store the data that needs to be live inline in the page.
If you are attaching something to the query string of the javascript file, you should move the static contents of the file to a seperate file that doesn't need regenerated each time. There is no need to reload 15 javascript functions with each page request because 1 contains dynamic content.