Here is my current setup:
I have a script on our Sharepoint.
Each user adds this in a bookmarklet to use it.
If I make an update, they have to go and set up the bookmark all over again.
What I want to do:
User adds script loader to bookmark toolbar
They click it, and it loads the script from our Sharepoint.
This way, if I need to make any changes, they don't have to do anything and changes will be reflected automatically.
My bookmarklets/scripts depend on jQuery to make ajax quests and just for general ease of use.
I am currently using this: http://benalman.com/projects/run-jquery-code-bookmarklet/
Is there a framework that I can use for this kind of thing? I know Visual Event uses a loader, but since it was compressed with Closure, I can't really tell what it's doing. I understand that since things are loaded asynchronously in Javascript, I would have to wrap all my code inside of jquery being loaded, which is fine.. I just need a way to do it.
all you need to do is move your bookmarklet code to an external js file, and then inject that file using a bookmarklet. That way, the bookmarklet injects the latest logic, and you don't have to ever re-bookmark again.
in that external script, you can paste the jQuery.js file's contents above your JS code to make sure it runs as expected.
modify the url to point to your script:
javascript:(function (){document.getElementsByTagName('head')[0].appendChild(document.createElement('script')).src='http://domain.com/scripts/external.js?'+Math.random();}());
if your intranet has decent caching setup, you can remove the "+Math.random()" part, but on an intranet, performance is rarely a problem for on-demand single-url asset loading, the the random url ensure everyone always gets the latest copy.
Related
We are developing a third party java script file that is implemented as a widget on many sites (That we do not control the code of).
This script may be updated from time to time (As we modify it/ add abilities/ fix bug ...)
As the browser saves most js files in cache, we need to have some sort of solution to tell the browser to reload the Script. of course a naive solution is to make re-load always, but this solution is not very efficient, and code changes should not accrue often.
Any idea how this can be done?
The solution of changing our script src/url with "?version=1.1.1" cannot be applied here as this widget is third party and we do not have any control on clients website codes.
Thanks.
Since you are the 3rd party and are giving your clients a link to the javascript file they need to include, have them point at your javascript with a url like this:
http://example.com/file.js
Then use a redirect on your server (Url Rewrite/htaccess etc) to point them to the latest version of that file. Lets say you versioned your script by putting it into a folder and your latest version was 1.3. You would setup the redirect from http://example.com/file.js to http://example.com/1.3/file.js. Then every time you release a new version, update your redirect to point to the new folder.
EDIT: More detailed explanation
When you add a script tag with an src field pointing to a javascript file, the browser gets it and executes it.
What I am wondering is how does this process work. Does the file get fetched and then somehow eval()'ed? Is it a mystical process that happens outside of the scope we have access? Or can we monitor/interfere this?
To explain what I want to achieve:
I want to give access to third parties to customize their page on my site by linking to their own javascript files. I want to be able to centrally log any errors that prevent those external scripts from loading (i.e. their server is down, parsing errors, whatever). Is it possible?
Thanks!
Obviously there are other ways to solve this such as hosting their scripts on my server and giving them a way to update them, but I 'm interested in knowing if my current approach is possible.
You can look at specific implementation in Firefox & Chromium sources with some grep magic, for your specific scenario I'd asynchronously subload those by inserting script tags on the fly and listening to global errors/events (eg window.onerror) from there.
It loads the java script file while loading the page and stores that script in its cache. If you load page another time then it will get that js from the cache.
I have a web service that works through giving users javascript to embed in their code. Users can also place that code on other sites to make it work there. However I also need to allow users to create a blacklist of sites that the JS should not function on. For example, a competitor or an inappropriate site.
Is there a way to check where our JS files are being loaded from, and block loading or break functionality on a per account basis?
Edit: The javascript loads an iframe on the site, so another solution would be to somehow block certain domains from loading an iframe from our server, or serve different content to that iframe
Edit 2: We're also trying to avoid doing this from with the JS because it could be downloaded and modified to get pass the block
Inspecting the url of the page
Yes, the javascript file, when it starts executing, can inspect window.url and see if the url of the main document is ok.
To see where the script was loaded from
It can also go through the dom, looking for the script node which brought in the javascript file itself and see from where the JS was loaded.
However
Anyone can load the javascript into a text editor, then change it to eliminate the tests, then host the modified JS on their own server. Obfuscating or minimizing the JS can slow someone down but obscurity is not security.
One thing you could do is have the javascript load another javascript file. That you serve from the server at a given url. The trick here is that that url will not go to a file but to a server end point that will return a javascript file. The you have that endpoint check for the routes for that user and decide if it will return the javascript you want to work or an error javascript of some kind.
This blog shows how to do it in php.dynamic-javascript-with-php
I'm developing a modal/popup system for my users to embed in their sites, along the lines of what KissInsights and Hello Bar (example here and here) do.
What is the best practice for architecting services like this? It looks like users embed a bit of JS but that code then inserts additional script tag.
I'm wondering how it communicates with the web service to get the user's content, etc.
TIA
You're right that usually it's simply a script that the customer embeds on their website. However, what comes after that is a bit more complicated matter.
1. Embed a script
The first step as said is to have a script on the target page.
Essentially this script is just a piece of JavaScript code. It's pretty similar to what you'd have on your own page.
This script should generate the content on the customer's page that you wish to display.
However, there are some things you need to take into account:
You can't use any libraries (or if you do, be very careful what you use): These may conflict with what is already on the page, and break the customer's site. You don't want to do that.
Never override anything, as overriding may break the customer's site: This includes event listeners, native object properties, whatever. For example, always use addEventListener or addEvent with events, because these allow you to have multiple listeners
You can't trust any styles: All styles of HTML elements you create must be inlined, because the customer's website may have its own CSS styling for them.
You can't add any CSS rules of your own: These may again break the customer's site.
These rules apply to any script or content you run directly on the customer site. If you create an iframe and display your content there, you can ignore these rules in any content that is inside the frame.
2. Process script on your server
Your embeddable script should usually be generated by a script on your server. This allows you to include logic such as choosing what to display based on parameters, or data from your application's database.
This can be written in any language you like.
Typically your script URL should include some kind of an identifier so that you know what to display. For example, you can use the ID to tell which customer's site it is or other things like that.
If your application requires users to log in, you can process this just like normal. The fact the server-side script is being called by the other website makes no difference.
Communication between the embedded script and your server or frames
There are a few tricks to this as well.
As you may know, XMLHttpRequest does not work across different domains, so you can't use that.
The simplest way to send data over from the other site would be to use an iframe and have the user submit a form inside the iframe (or run an XMLHttpRequest inside the frame, since the iframe's content resides on your own server so there is no cross domain communication)
If your embedded script displays content in an iframe dialog, you may need to be able to tell the script embedded on the customer site when to close the iframe. This can be achieved for example by using window.postMessage
For postMessage, see http://ejohn.org/blog/cross-window-messaging/
For cross-domain communication, see http://softwareas.com/cross-domain-communication-with-iframes
You could take a look here - it's an example of an API created using my JsApiToolkit, a framework for allowing service providers to easily create and distribute Facebook Connect-like tools to third-party sites.
The library is built on top of easyXDM for Cross Domain Messaging, and facilitates interaction via modal dialogs or via popups.
The code and the readme should be sufficient to explain how things fit together (it's really not too complicated once you abstract away things like the XDM).
About the embedding itself; you can do this directly, but most services use a 'bootstrapping' script that can easily be updated to point to the real files - this small file could be served with a cache pragma that would ensure that it was not cached for too long, while the injected files could be served as long living files.
This way you only incur the overhead of re-downloading the bootstrapper instead of the entire set of scripts.
Best practice is to put as little code as possible into your code snippet, so you don't ever have to ask the users to update their code. For instance:
<script type="text/javascript" src="http://your.site.com/somecode.js"></script>
Works fine if the author will embed it inside their page. Otherwise, if you need a bookmarklet, you can use this code to load your script on any page:
javascript:(function(){
var e=document.createElement('script');
e.setAttribute('language','javascript');
e.setAttribute('src','http://your.site.com/somecode.js');
document.head.appendChild(e);
})();
Now all your code will live at the above referenced URI, and whenever their page is loaded, a fresh copy of your code will be downloaded and executed. (not taking caching settings into account)
From that script, just make sure that you don't clobber namespaces, and check if a library exists before loading another. Use the safe jQuery object instead of $ if you are using that. And if you want to load more external content (like jQuery, UI stuff, etc.) use the onload handler to detect when they are fully loaded. For example:
function jsLoad(loc, callback){
var e=document.createElement('script');
e.setAttribute('language','javascript');
e.setAttribute('src',loc);
if (callback) e.onload = callback;
document.head.appendChild(e);
}
Then you can simply call this function to load any js file, and execute a callback function.
jsLoad('http://link.to/some.js', function(){
// do some stuff
});
Now, a tricky way to communicate with your domain to retrieve data is to use javascript as the transport. For instance:
jsLoad('http://link.to/someother.js?data=xy&callback=getSome', function(){
var yourData = getSome();
});
Your server will have to dynamically process that route, and return some javascript that has a "getSome" function that does what you want it to. For instance:
function getSome(){
return {'some':'data','more':'data'};
}
That will pretty effectively allow you to communicate with your server and process data from anywhere your server can get it.
You can serve a dynamically generated (use for example PHP or Ruby on Rails) to generate this file on each request) JS file from your server that is imported from the customers web site like this:
<script type="text/javascript" src="//www.yourserver.com/dynamic.js"></script>
Then you need to provide a way for your customer to decide what they want the modal/popup to contain (e.g. text, graphics, links etc.). Either you create a simple CMS or you do it manually for each customer.
Your server can see where each request for the JS file is coming from and provide different JS code based on that. The JS code can for example insert HTML code into your customers web site that creates a bar at the top with some text and a link.
If you want to access your customers visitors info you probably need to either read it from the HTML code, make your customers provide the information you want in a specific way or figure out a different way to access it from each customers web server.
I'm talking about something like GreaseMonkey but that would accept the script just as it would be on the website. Adding external scripts to Greasemonkey has been a pain for me so far.
So, I have a client who wanted me to write a specific script for him. Because the script reads the URL of the page visited by a user I can only test it on the website but i don't have access to the source code of the website. I'd like to make sure I deliver to the client a 100% working script so I would love to test it first.
How can I do that? Any plugins that would just allow me to copy the script and would run it every time I load a page of the website?
Obviously, if you can, you want to set up a copy of the page on which the script operates, on a local web server where you can play around with things.
If that isn't possible for whatever reason, you can inject your script directly into their site when you're looking at it with your browser using a bookmarklet. The code to do it is roughly:
var script = document.createElement('script');
script.src = "...the path to your script file, ideally on a local web server rather than a file:// path...";
document.body.appendChild(script);
Once you've tweaked the above (pretty much just supplying the src value), you can turn it into a bookmark via the Crunchinator. Once you have your bookmarket, just visit the site you're developing this for and click your bookmarklet, and your script will be added to the page (just for you, obviously, and just for that visit to the page).
Then your develop/test cycle becomes:
Modify the script file (for instance, to fix a bug)
Open their site
Click your bookmarklet to add your script file to the page
Using something like GreaseMonkey can lead to unexpected results since GM runs outside of the Browsers Sandbox and GM scripts always run after everything else has loaded.
My solution for this would probably be:
Setup a local WebServer
Use "Save page..." to get the page contents, then put them on your localhost
Now add your script to the page etc. and make it work
That gives you A) A flexible development environment and B) more "realworld" results, hell you can even edit you hosts file to use the same URL that your client's page has (of course you need to re-edit the file if you want to visit the original page) and C) you can test in IE etc. too.