dojo load js script and then execute it - dojo

I am trying to load a template with xhr and then append it to the page in some div.
the problem is that the page loads the script but doesn't execute it.
the only solution I got is to add some flags in the page (say: "Splitter"), before the splitter, I put the js code, and after the splitter I add the html code, and when getting the template by ajax, I split it. here is an example:
the data I request by ajax is:
//js code:
work_types = <?php echo $work_types; ?>; //json data
<!-- Splitter -->
html code:
<div id="work_types_container"></div>
so the callback returns 'data' which I simply split and exeute like this:
data = data.split("<!-- Splitter -->");
dojo.query("#some_div").append(data[1]); //html part
eval(data[0]); //js part
Although this works for me, but it doesn't seem so professional!
is there another way in dojo to make it work?

If you're using Dojo, it might be worth to look at the dojox/layout/ContentPane module (reference guide). It's quite similar to the dijit/layout/ContentPane variant but with one special extension, that it allows executing the JavaScript on that page (using eval()).
So if you don't want to do all that work by yourself, you could do something like:
<div data-dojo-type="dojox/layout/ContentPane" data-dojo-props="href: myXhrUrl, executeScripts: true"></div>
If you're concerned about it being a DojoX module (DojoX will disappear in Dojo 2.0), the module is labeled as maintained, so it has a higher chance of being integrated in dijit in later versions.
As an anwer to your eval() safety question (in comments). Well, it's allowed of course, else they wouldn't have such a function called eval(). But indeed, it's less secure, the reason for this is that the client in fact trusts the server and executes everything the server sends to the client.
Normally, there are no problems unless the server sends malicious content (this could be due to an issue on your server or man in the middle attacks) which will be executed and thus, causing an XSS vulnerability.
In the ideal world the server only sends data and the client interpretes this data and renders it by himself. In this design, the client only trusts data from the server, so no malicious logic can be executed (so there will be no XSS vulnerability).
It's unlikely that it will happen and the ideal world solution is not even possible in many cases since the initial page request (loading your webpage) is in fact a similar scenario where the client executes whatever the server sends.
Web application security is not about being 100% safe (it's impossible), but it's to try to create as less as possible open doors that can be used by hackers. It's up to you what you consider safe and to verify if the "ideal world" solution is possible in this specific scenario (it might not be, or it might take too much time compared to the other solution).

Related

Updates using server-side rendering without page refresh

I was reading an interesting blog. Here the author said:
Updates using server-side rendering is where a lot of developers start
going off the deep end. They actually think page refresh. Instead,
what I thought we've all been doing for the last half decade, is some
form of:
$('#loadTweets').on('click', function(e) {
$.get('/tweets/person', {last_id: 239393939}, function(r) {
$('#tweets').prepend(r);
});
e.preventDefaults();
});
In other words, we are still only doing a partial update, but letting
the server do the rendering and inserting that finalized output into
our DOM.
I did not understand what he meant by "is some form of:...we are still only doing a partial update".
I mean, if I understood correctly, server sending the html and css on every request is Server-Side Rendering (SSR). Server sending json on every request except first is Client-Side Rendering (CSR).
As far I understand, in the code bellow, if r is json then it is CSR and if r is html then it is SSR:
$.get('/tweets/person', {last_id: 239393939}, function(r) {
$('#tweets').prepend(r);
});
What am I getting wrong here?
Bassed on your definition of SSR vs CSR
Server sending [HTML] on every request is Server-Side Rendering (SSR)
Server sending [JSON] on every request except first is Client-Side Rendering (CSR).
let's try to apply that to the example logically:
$.get('/tweets/person', {last_id: 239393939}, function(r) {
// do stuff with `r`
});
For that I made your statements into this decision table. (I'll get to the undefined cases right away, keep reading.)
First Response?
JSON
HTML
Yes
undefined
SSR
No
CSR
undefined
First, we check whether it's the first request. We can say without problems that it is not, wouldn't the client have gotten the JavaScript earlier it couldn't be running it.
Now let's introduce what type of data is send:
if [response] is json then it is CSR
if [response] is html then it is SSR
The first statement is valid, it would definitely be CSR. But the second one would lead an undefined case. We're deeply confused now!
To address that, let's read how the author defines as CSR and SSR:
With client-side rendering, your initial request loads the page layout, CSS and JavaScript. It's all common except that some or all of the content isn't included. Instead, the JavaScript makes another request, gets a response (likely in JSON), and generates the appropriate HTML (likely using a templating library).
With server-side rendering, your initial request loads the page, layout, CSS, JavaScript and content.
For now, this leads to a similar table than yours, but note how the format/type headers are slightly different!
First Response?
Data as JSON
Data as HTML
Yes
undefined
SSR
No
CSR
undefined
S/He continues:
For subsequent updates to the page, the client-side rendering approach repeats the steps it used to get the initial content. Namely, JavaScript is used to get some JSON data and templating is used to create the HTML.
So s/he's now at the second row of his table, i.e. not the first response.
Then your quote starts (emphasis mine):
Updates using server-side rendering is where a lot of developers start going off the deep end. They actually think page refresh. Instead, what I thought we've all been doing for the last half decade, is some form of [...] doing a partial update, [...] letting the server do the rendering [of the HTML] and inserting that finalized output into our DOM.
With this we can fix the undefined case in the not-first-request-row we have been confused about!
First Response?
JSON
HTML
Yes
undefined
SSR
No
CSR
Partial Update
There is still the first-response-JSON-case, but as the browser cannot generate further requests from this on it's own we can ignore it here.
Hope this helps!

Data sharing mechanism

I need to develop a web application, where our data/html need to be displayed on third party sites using iframe or javascript. Example: cricket widget sharing.
Can someone tell me what type development is it called ?
There would be multiple kind of widget, some of them will also need to be upgrded short periodically (per x second).
Also, should i use iframe or use javascript implemenration merhod to generate the output on clients server.
Can someone provide me a reference or idea ?
Considering I have understood your question rightly, which means you currently need to develop a widget(not a web app) for websites. A widget is something that can be used by others on their websites.
Adding to the above understanding with the example you gave-
Say you develop a Cricket widget, 100's of other websites can put this widget on their site using a small piece of API or code. And, this widget refreshes every 'x' seconds to display Live Score. Hope this is what you need.
Here is the solution/way to solve this:
What you have to do is write an embedder or loader script keeping the following points in mind-
Make it asynchronous, so that the client website doesn't slow down
Keep it short. Abstract your code. Don't give the user 100's of lines.
Preferably don't use a framework. Chances are it can conflict with your client's website/frameworks. Don't even use jQuery!(Because it can conflict with user's jquery version and cause lot of problems to the widget and website) Write pure Javascript code :)
Don't ever use GLOBAL variables. Use var or let and follow best practices. Using global variables may conflict with user's variables and the whole website/client can get messed up.
A sample code -
<script data-version='v1' data-widget-id='your-clients-id' id='unique-embedder-id' type='text/javascript'>
// "data-version": It's useful to put the version of your embedder script in the "version" data attribute.
// This will enable you to more easily debug if any issues arise.
// "data-widget-id": This ID allows us to pull up the correct widget settings from our database.
// It's a "client id" of sorts.
// "id": This HTML id allows us to refer to this embedder script's location. This is helpful if you want to inject html
// code in specific places in hour hosts's website. We use it to insert our payload script into the <head> tag.
//We wrap our code in an anonymous function to prevent any ofour variables from leaking out into the host's site.
(function() {
function async_load(){
//BELOW: we begin to construct the payload script that we will shortly inject into our client's DOM.
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
// Below is the URL you want them to get your payload script from!
var theUrl = 'http://www.your-website.com/assets/your-payload-script.js';
// At the end we tack on the referrer's URL so we know which website is asking for our payload script.
s.src = theUrl + ( theUrl.indexOf("?") >= 0 ? "&" : "?") + 'ref=' + encodeURIComponent(window.location.href);
// This finds the location of our embedder script by finding the element by it's Id.
// See why it was useful to give it a unique id?
var embedder = document.getElementById('unique-embedder-id');
// This inserts our payload script into the DOM of the client's website, just before our embedder script.
embedder.parentNode.insertBefore(s, embedder);
}
// We want the our embedder to do its thing (run async_load and inject our payload script)
// only after our client's website is fully loaded (see above).
// Hence, we wait for onload event trigger. This no longer blocks the client's website from loading!
// We attachEvent (or addEventListener to be cross-browser friendly) because we don't want to replace our
// client's current onLoad function with ours (they might be doing a bunch of things on onLoad as well!)
if (window.attachEvent)
window.attachEvent('onload', async_load);
else
window.addEventListener('load', async_load, false);
})();
</script>
Read the comments. They are very helpful :)
Your users will have to just use a nicely abstracted script tag-
<script type="text/javascript" src="http://example.com/widget.js"></script>
Or maybe even an iFrame(old is gold days) render HTML in iFrame(Best way if you don't want to 'openly' expose(as most won't know) your Abstracted Javascript as well)
<iframe src="http://example.com/mywidget.html"></iframe>
Here are the references that I referred and also have sample widgets which can be reused-
Developing an Embeddable Javascript Widget / Snippet for Client Sites
Creating an Embeddable JavaScript Widget
Creating Asynchronous, Embeddable JavaScript Widgets
Building an embeddable Javascript widget (third-party javascript)
One last time, please don't use global variables and write asynchronous code. These 2 are the main things that you have to take care to make a great/successful widget with top-notch performance.
Happy Coding! Hope it helps :)

Asynchronous Pluggable Protocol for CID: (email), how to handle duplicate URLs

This is somewhat a duplicate of this question, but that question has no (valid) answer and is 1.5 years old so asking my own with hopes people have more info now.
If you are using multiple instances of a WebBrowser control, MSHTML, IHTMLDocument, or whatever... from inside the APP instance, mostly IInternetProtocol::Start, is there a way to know which instance is loading the resource? Or is there a way to use a different APP for each instance of the control, maybe by providing one via IDocHostUIHandler or ICustomDoc or otherwise? I'm currently using IInternetSession::RegisterNameSpace to make it process wide.
Optional reading below, don't feel you need to read it unless above isn't clear.
I'm working on a legacy (Win32 C++) email client that uses the MS ActiveX WebBrowser control (MSHTML or other names it goes by) to display HTML emails. It was saving everything to temp files, updating the cid: URLs, and then having the control load that. Now I want to do it the correct way, using APP. I've got it all working with some test code that just uses static variables/globals and loads one email.
My problem now is, the app might have several instances of the control all loading different emails (and other stuff) at the same time... not really multiple threads so much, just the asynchronous nature of the control. I can give each instance of the control a unique URL to load the email, say, cid:email-GUID, and then in my APP code I can use that URL to know which email to load. However, when it comes to loading any content inside the email, like attached images using src="cid:", those will not always be unique so I will not always know which image it is, for which email. I'd like to avoid having to modify the URLs of the HTML before displaying it (I'm doing that now for the temp file thing, but want to do it a better way).
IInternetBindInfo::GetBindString can return the referrer, BINDSTRING_XDR_ORIGIN, or the root URL, BINDSTRING_ROOTDOC_URL, but those require newer versions of IE and my legacy app must support older XP installs that might even have IE6 or IE7, so I'd rather not use these.
Tagged as TWebBrowser because that is actually what I'm using (Borland Builder 6 C++), but don't need answers specific to that platform.
As the Asynchronous Pluggable Protocol Handler us very low level, you cannot attach handlers individually to different rendering controls.
Here is a way to get the referrer:
Obtain BINDSTRING_HEADERS
Extract the referrer by parsing the line Referer: http://....
See also How can I add an extra http header using IHTTPNegotiate?
Here is another crazy way:
Create another Asynchronous Pluggable Protocol Handler by calling RegisterMimeFilter.
Monitor text/plain and text/html
Scan the incoming email source (content comes incrementally) and parse store all image links in a dictionary
In NameSpaceHandler you can use this dictionary to find the reference of any image resources.

How to handle errors in Zope page templates

I'm looking for a good way to handle errors in Zope's page templates. What I already know is:
<div ... tal:define=...
tal:on-error="string:Oops!">
This text will be replaced in case of errors
</div>
or
<div ... tal:define=...
tal:on-error="error/value">
This text will be replaced in case of errors
</div>
or
<div ... tal:define=...
tal:on-error="string:${error/type}: ${error/value}">
This text will be replaced in case of errors
</div>
However, it might be desirable to use a more elaborated error handling method, e.g.
to display details depending on certain permissions
to log and/or report the error to the maintainers
to have an easy way to create some pretty HTML without the need of a lot of code in the template
I had a look at the old Zope documentation page and created a script object like described there (amending the missing colon, of course); however, it won't work (I tried both on-error="here/errHandler" and on-error="here/scripts/errHandler", and I added *args and **kwargs, without success).
I tried to build a browser (on-error="here/##talerror") for such purposes, and it was used alright, but it didn't seem to get the error object.
I'm using Zope 2.10.7-final and Plone 3.3 (old, I know).
Is there a way to hand over the error object to the browser, or to make the script object work?
P.S., just to get it clear: This is not about sqeezing lots of logic in a template - no sermons about templates and logic, please! My goal is to find the error in existing templates, i.e. which part of the logic (which is implemented somewhere behind the scenes, in browsers etc.) fails in which way. The documented way of using an error script doesn't work for me (maybe I'm missing an important part?), and an error handling browser apparently doesn't have access to the error object.

JMeter Tests and Non-Static GET/POST Parameters

What's the best strategy to use when writing JMeters tests against a web application where the values of certain query-string and post variables are going to change for each run.
Quick, common, example
You go to a Web Page
Enter some information into a form
Click Save
Behind the scenes, a new record is entered in the database
You want to edit the record you just entered, so you go to another web page. Behind the scenes it's passing the page a parameter with the Database ID of the row you just created
When you're running step 5 of the above test, the page parameter/Database ID is going to change each time.
The workflow/strategy I'm currently using is
Record a test using the above actions
Make a note of each place where a query string variable may change from run to run
Use a XPath or Regular Expression Extractor to pull the value out of a response and into a JMeter variable
Replace all appropriate instances of the hard-coded parameter with the above variable.
This works and can be automated to an extent. However, it can get tedious, is error prone, and fragile. Is there a better/commonly accepted way of handling this situation? (Or is this why most people just use JMeter to play back logs? (-;)
Sounds to me like your on the right track. The best that can be achieved by JMeter is to extract page variables with a regular expression or xpath post processor. However your absolutely correct in that this is not a scalable solution and becomes increasingly tricky to maintain or grow.
If you've reached is point then you may want to consider a tool which is more specialised for this sort of problem. Have a look web testing tool such as Watir, it will automatically handle changing post parameters; but you would still need to extract parameters if you need to do a database update but using Watir allows for better code reuse making the problem less painful.
We have had great success in testing similar scenarios with JMeter by storing parameters in JMeter Variables within a JDBC assertion. We then do our http get/post and use a BSF Assertion and javascript do complex validation of the response. Hope it helps