-
Notifications
You must be signed in to change notification settings - Fork 340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Precompile jsrender templates to avoid unsafe-eval #336
Comments
I will need to work on adding this as a new feature. I'm not sure yet whether to add it to the V1.0 version that is planned soon, or whether to make it post V1.0. But I have a prototype implementation that you could test, and let me know your thoughts. Here is the prototype (based on my current working version so has some other changes since V0.9.90): Here is how it works. New API:
which does pre-compilation, with eval/new Function calls, with same signature options as $.templates(...): markupString / name, markupString / hash of markupStrings for named templates. It returns an object or a hash of 'precompiled template' objects, which are plain javascript objects, with properties:
You can also run it without parameters, in a page that has already got any number of registered templates, and it will return the precompiled objects for that page. You can run it on the server or in a different time frame, and store the precompiled template objects. Then at runtime in the browser you can pass exactly the returned object/hash/tree of objects to the normal $.templates method in order to establish the normal template registration, but this will use the pre-compiled functions and will not need to do eval. It will also be faster, and can run on a page with a a lightweight jsrender.runtime.js with no compilation code, if we make that available.
Of course you can hand-optimize the compiled functions, Usage example:
|
That looks very promising, thanks! Since this is not a breaking API change, it would be great if you could put it in the V1 release. But of course, I leave that decision up to you. I tried the prototype. It works well with toplevel templates, but it seems to break on subtemplates introduced by
|
Yes, you are right - the implementation was incomplete. (It was more of a proof of concept). Here is an update that should work for a range of scenarios: jsviews.js.txt. It will work with both JsRender and with JsViews. So even in JsViews, all calls to new Function can be avoided by precompiling. One technique for obtaining the compiled object hierarchy that you need to server-render into the page's javascript (or add statically to the HTML page) is to include
You will need this updated jsonview.js, though: jsonview.js.txt Then you simply select and copy-paste the rendered object hierarchy to your HTML page and pass is to $.templates() to register the templates:
|
Great! That updated version indeed works quite well. I looks like that modified version of
|
Yes, it was skipping all properties of type function (per previous scenarios it was used for). jsonview.js.txt But it will need to be used with the corresponding updated jsviews.js, which is here: With this version you can still opt in to the previous behavior by setting |
Hi Robbert, just to let you know that I am working more on this potential feature. Current code is of course not yet working completely (the jsviews.js.txt above) but I will keep you posted here of progress.... |
I'm happy to hear that. Thank you again for the effort you're putting into this! |
Unfortunately, I've decided against moving ahead with this feature. It looked promising, but:
|
That's too bad, but I understand your decision, now that it turns out to be unfeasible to make it work in the general case. For me personally, however, I think that the special cases in which it does work are sufficient, as I'm only using JsRender and (probably) don't do any of the things that require on-the-fly compilation. Coming back to my original purpose, which is getting rid of |
I'll try to look into alternatives as some point, but probably not until after getting out the next update (which is overdue).... I'll keep this open now, to track that... |
Closing for now, but added an After V1? label. I'll consider reopening at some point. (But no promises :) ...) |
Hi, is there any plan to get rid of 'unsafe-eval' in our Content Security Policy, Good that we got Eval function case resolved long back but still the 'new Function' is trouble creator. |
No plan for the moment. (Although we may re-consider this in the future...). See also the discussion here. |
Hi, I know this issue is closed but we need to have JSRender work with precompiled version of templates in a CSP environment with no eval() or new Function(). Adding this to a future release will help our project a lot. |
Hello, do you have any plan to add this feature soon? Should we wait or it won't come out? |
Unfortunately, following earlier attempts, and associated issues (as discussed earlier in this thread), there is no current plan to provide this feature. |
For implementing our Content Security Policy I would like to avoid any code that uses
eval()
ornew Function
, so that I don't have to addunsafe-eval
to the CSP. However, JsRender usesnew Function
to compile templates.Is there a way to avoid this or work around it? Is it on the JsRender roadmap?
Note: I was thinking of solving this by precompiling our templates on the server (something like http://handlebarsjs.com/precompilation.html), so that I only need to render on the client. When I examine the code, it looks like I could make it work by serializing the compiled template (i.e., the result of calling
compileTmpl
), including all its subtemplates, to a JSON-string on the server, putting that in a<script>
tag and then use that to render.One of the issues I'm running into with this approach, is that the compiled templates also contain a reference to a
render
function, which is internal to JsRender. I would have to expose it to be able to use it on the client, I think.The text was updated successfully, but these errors were encountered: