JavaScript Injection On Third-Party Pages - javascript

I've recently stumbled upon a website called Overlay101 which allows you to create tours for other websites.
I was very interested to see the technique they use to load the third party websites for editing.
When you type the address of the website, it is loaded as a sub domain of the overlay101.com website.
For example, if I type https://stackoverflow.com/questions/111102/how-do-javascript-closures-work - it is loaded as http://stackoverflow.com.www.overlay101.com/questions/111102/how-do-javascript-closures-work
I was wondering how is that subdomain creation achieved and I saw in the source code of the page that JavaScript in injected. I was wondering how was that possible too.
What intrigued me most is that Stackoverflow.com does not allow pages to be loaded within frames - I was wondering how they managed to load up the page so that tour popups could be added.

They simply use wildcard DNS entries to make all subdomains work. They then use the Host header to get the original domain name and download the HTML code of the site. Since they do this on the server side they do not need any frames etc.

Related

Loading Specific Elements Cross Domain

I am trying to design a web page (PHP) that extracts certain elements loaded up by and external website and displays it in my own format on my website. I have seen many things regarding this, but they all seem to work with a the Same Site Origin Policy only.
Another issue is that the first element loaded is a text input that needs to be submitted in order to load up what I'm ultimately trying to retrieve, so how can I got about putting this in my page aswell?
Example of layout:
Notice that Page 1 is basically a search. It requires input in order to retrieve the 2nd page.
Now a few of the methods that I've looked into:
jQuery.load
The problem with this is that the website files being loaded need to be local. From my understanding, jQuery doesn't support cross domain due to security reasons. And also I'm unsure of how I would go about inputting the required info to load page 2.
Ajax Method From
Ways to circumvent the same-origin policy
This method seems promising but the problem here is that I need access to the external website files, and in my case that can't happen. Also unsure of how to implement a POST and GET in order to load page 2.

Using a Chrome extension content script to embed additional content

I am working on a Chrome extension that will add content to a particular set of pages. From my research, it sounds like what I want is a content script that will execute for the appropriate pages. I can specify the "appropriate pages" using the content_script.matches manifest.json field.
However, the problem I'm running into is that content scripts run in an isolated world, separate from the rest of your extension.
How I had envisioned my extension was a set of UI pages that would be embedded on the appropriate pages by the content script. The background page would contain the code for build the content of the UI pages. The background page, and by extension, the UI pages, would need access to the various Chrome APIs (e.g., local storage), as well as being able to make cross-domain requests to retrieve their data. However, it seems this is not possible, since the content scripts run in an isolated world, and don't have access to the Chrome APIs that I need.
Message passing allows a content script to send and receive data from the background page, but doesn't allow you to take a UI page and embed it on the current webpage.
I initially thought I was making some headway on this when I was able to make a jQuery AJAX request from my content script for an UI page, but that only gets me the HTML file itself. My UI pages depend on code to programmatically build the content--it's not just a static HTML page. And that "build the page" JavaScript code depends on Chrome APIs that are not available to the content script. So, if I just tried to make all my UI pages and JavaScript resources web_accessible_resources, I could inject them into the page but they wouldn't be able to run.
Which brings me to my question: how can a content script pull down, or embed, UI pages that can invoke code in the background page?
Tldr: you need to read about sending messages between content/background. Its in the docs and many samples.
From what I've been able to find, the architecture I was hoping for (as outlined in my question) is not possible in a Chrome Extension. Chrome's security model requires a different approach. Here's what worked for me.
Make your templates, JavaScript files, and anything that's part of your UI, web_accessible_resources.
Use your content script to load these resources and display them to the user at the appropriate times/locations.
(Almost) any calls to chrome.* API need to be done through your background page or event page. In my case, the "background page" is strictly JavaScript, there's no HTML.
Your content script, and UI, can send messages to your background/event page(s).
This model is not unlike the traditional client/server architecture of a web app. The "background page" is like your server, and your content script can send "messages" (think HTTP request) to the "background page" just like it might send a request to your server.
The background page, just like the server, has access to resources that the content script does not, e.g., the background page can use more of the chrome APIs.
This mental analogy helped me to "redesign" my app in a way that (so far) is working within the Chrome Extension security model. I had originally been thinking more along the lines of a traditional desktop app, where the entire app can do things like make cross domain requests or write to the file system. Chrome Extensions and Apps don't work this way, however.

IE Restrict JavaScript third party domain access other than *.currentwebsite.com

It is possible to disable JS at all.
It is possible to disable JS on certain domains by adding them to Restricted Zone for example.
I wonder if it is possible to block/restrict third party domain access other than *.currentwebsite.com for enabled JS in IE.
This could be somehow useful in ad blocking as well as security.
Or am I supposed to write an add-on myself?
I don t know is it possible or not but it is definitely a bad idea as CDNs are highly popular these days and most of the page use these for CSS and JS file as well as image file.
To block ads you can also use hosts file (under system32\drivers\etc folder) if you have the list of the URLs (I am pretty sure you can find a list at the internet) just redirect them some fake address like localhost or a server response nothing.

How do JavaScript-based modal/popup services like KissInsights and Hello Bar work?

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.

Can I host a file or folder on another person's domain?

I don't think this is possible, but it never hurts to ask.
Is there any way for me to host a file (or folder) on someone else's domain (with their permission, of course)? For example, if their site is hosted at www.example.com, I would like to host a file at www.example.com/foo.html, or a folder at www.example.com/foo/, or the like. I just need to be able to make changes at will to a single file.
We can't use a redirect or anything like that - the purpose of this is to allow me to control a document loaded in an <iframe> on their site, and for the JavaScript in that <iframe> to have access (i.e., no security restrictions) to its parent page - which is only allowed if the domains match. Their site doesn't change the document.domain property to relax the security restrictions, nor can we ask them to start using that approach (it's an enormous site).
I also can't generate an <iframe> and create its document solely using JavaScript - we've done that in the past, and it gets around the security restrictions (the generated <iframe> is in the same domain as its parent page), but it causes other issues and difficulties that add up to a deal-breaker in this case.
Please let me know if you have any alternative suggestions, or if you need any more information about what exactly I'm trying to do.
Thanks in advance for any help!
I hope I'm understanding this correctly. Since you have their permission to host a file on their site, can you just use FTP? They can set you up to only be able to drop files in one directory on their site, and you can edit the file there.
Provide embed code to the other party to load remote javascript file to their page. You may then generate content or information gathering. As the javascript file is hosted on your side, it's under your control. A Visitor Counter is a similar case.
You could make a php script that loads it's data from your own site.
this should work actually:
<?php echo file_get_contents("http://www.yoursite.com/yourfile.html"); ?>
Edit: You might be able to do the same with javascript, but i don't know the code for it... Sorry. :-/
Sounds like your friend can set up a reverse proxy rule on their web server for your file. http://httpd.apache.org/docs/2.0/mod/mod_proxy.html

Categories

Resources