sending a message from a web app to an extension - google-chrome-extension

I have an extension which provides a number of services to any web app that requires them. I had been assuming that a web app could use chrome.runtime.sendMessage(ext-id,message), but when I try, there is no sendMessage function on chrome.runtime.
Have I misunderstood where sendMessage can be used, and is there another technique that I can use to communicate from an arbitrary web app to my extension?

There are a few options.
First, http://developer.chrome.com/extensions/manifest/externally_connectable.html is the closest to how you're thinking about it right now. You're expecting to be able to add proprietary, Chrome-specific functionality to arbitrary web pages. externally_connectable will give you a limited version of (see http://developer.chrome.com/extensions/messaging.html#external-webpage for an example), but only for specific web pages (e.g., *.yourdomain.com but not *.com).
Second, you can postMessage from your web page to a content script (see http://developer.chrome.com/extensions/content_scripts.html#host-page-communication), which can do anything a content script can. If you need chrome.* APIs at that point, you can message from the content script to your extension's page, which has access to any chrome.* APIs that it's asked for.
Finally, depending on what your "number of services" actually is, you can always executeScript another script directly into a target webpage, which is similar to forcing the webpage to include it as if it were another <script> tag. (Only similar to, not identical to, because the injection typically happens after the page has loaded.)

Related

How to embed a web browser inside a web app made in node.js ?

I currently have a web app made in node.js. One feature of this app is to take notes. I want to provide the user with a way to browse the internet and select a text to add as a note in our web app without having to manually copy-pasting from one browser window to our app.
I know I can do this relatively simply using a Chrome extension that would be linked to the user account and would save the note to the database. However, I cannot use this approach since not all my users can install Google Chrome.
Therefore, I am looking for a way to browse the web from inside our web app. For example, it could be in an iFrame where we display a complete browser. That way, the user could navigate the web for information from inside the app, select text to save and click on a button (probably located outside the iFrame browser) to save the selected text as a note in our database.
How can I achieve such a thing in node.js ?
This is, essentially, impossible.
For you to get any data about the site the user was browsing you could either:
Restrict them to browsing sites willing to partner with you to give you permission to access their data via postMessage (a technical change on their part to work around the Same Origin Policy)
Proxy every request through your server which would:
Have large bandwidth requirements
Require a lot of rewriting of URLs (including dynamically generated ones in JS)
Require rewriting of X-Frames-Options and Access-Control-Allow-Origin headers
Need users who would trust you with all the data you passed through your system (including their passwords to third party sites)
Not work for Intranet sites (since your server could not reach them)

Call Google Chrome extension function from any website, without modifying the extension?

I created a question a few minutes ago here: How to modify Chrome Extension, which authenticates every user through Google's OAuth 2?
However, it seems like the CRX files are signed, which means I cannot modify the extension. However, I know exactly how the extension works. Basically I need to do call a function, while parsing it a string. Is that possible to do through my website? The function from the background.js could look like this:
function sendAlert(message) {
alert(message);
}
Is it possible to call sendAlert() from my website?
It's not possible to directly access an extension from a web page.
A web page can communicate with an extension in two cases:
the extension expects external connections via, for example, runtime.onMessageExternal.
the extension listens to DOM events of the page in its content script AND there's an event that triggers the behavior you need

How to use dropbox API from chrome extension content script?

If I write a chrome extension, it normally consist of multiple parts:
One is the devtools page which is a normal HTML page with origin set to
"chrome-extension://<guid>/filename". On that page I can use
the Dropbox API to get user confirmation via HTML popup and then use
the saved auth info and do all work via the Dropbox javascript library.
Another part of extension is the content script which is executed
in the context of specified third-party web pages ("injected") and have
origin cookies and web storage shared with them.
Is it possible to also use the Dropbox JavaScript library in that content script?
I can't call authenticate in interactive mode since it will re-ask for confirmation for each different webpage I'm injected into. And calling authenticate without interactive will fail since the content script doesn't share the origin, cookies and web storage with the devtools extension page :(. Maybe there's some way to "pass" the Dropbox auth info from the part of the extension that offers GUI and where user successfully confirms dropbox usage to the parts of the extension that are GUI-less, like content script or background page?
I have managed to get Facebook working from code injected into a web app via a content script. I suspect there are multiple ways, but what I did was take advantage of the chrome.identity API to do the OAuth work for me, specifically the launchWebAuthFlow().
This can only be done in the background page (in my case an event page), but I send messages to the event page which replies with the access_token, which can then be used in URLs in the same was as the 'web' technique - i.e. in HTTP requests with XHR.
You can send/receive messages via the content script (using events on document), but I decided to do it directly using "external" messages with the chrome.runtime.sendMessage() API in the web app context, and chrome.runtime.onMessageExternal() in the background script. This requires adding "matches" for the URLs you're injecting code into in an "externally_connectable" section of the manifest.json.
I believe this can be adapted to make it work with Dropbox.

How can I pass a message from outside URL to my Chrome Extension?

I know there's a way for extensions and pages to communicate locally, but I need to send a message from an outside URL, have my Chrome Extension listen for it.
I have tried easyXDM in the background page, but it seems to stop listening after awhile, as if Google "turns off" the Javascript in the background page after awhile.
I think you may try some walk around and build a site with some specific data structure, and then implement a content script which will look for this specific that specific data structure, and when i finds one it can fetch the data you want to be passed to your extension.
Yes, you need a content script that communicates with the page using DOM Events.. Instructions on how to do that are here:
http://code.google.com/chrome/extensions/content_scripts.html#host-page-communication

how to check if my website is being accessed using a crawler?

how to check if a certain page is being accessed from a crawler or a script that fires contineous requests?
I need to make sure that the site is only being accessed from a web browser.
Thanks.
This question is a great place to start:
Detecting 'stealth' web-crawlers
Original post:
This would take a bit to engineer a solution.
I can think of three things to look for right off the bat:
One, the user agent. If the spider is google or bing or anything else it will identify it's self.
Two, if the spider is malicious, it will most likely emulate the headers of a normal browser. Finger print it, if it's IE. Use JavaScript to check for an active X object.
Three, take note of what it's accessing and how regularly. If the content takes the average human X amount of seconds to view, then you can use that as a place to start when trying to determine if it's humanly possible to consume the data that fast. This is tricky, you'll most likely have to rely on cookies. An IP can be shared by multiple users.
You can use the robots.txt file to block access to crawlers, or you can use javascript to detect the browser agent, and switch based on that. If I understood the first option is more appropriate, so:
User-agent: *
Disallow: /
Save that as robots.txt at the site root, and no automated system should check your site.
I had a similar issue in my web application because I created some bulky data in the database for each user that browsed into the site and the crawlers were provoking loads of useless data being created. However I didn't want to deny access to crawlers because I wanted my site indexed and found; I just wanted to avoid creating useless data and reduce the time taken to crawl.
I solved the problem the following ways:
First, I used the HttpBrowserCapabilities.Crawler property from the .NET Framework (since 2.0) which indicates whether the browser is a search engine Web crawler. You can access to it from anywhere in the code:
ASP.NET C# code behind:
bool isCrawler = HttpContext.Current.Request.Browser.Crawler;
ASP.NET HTML:
Is crawler? = <%=HttpContext.Current.Request.Browser.Crawler %>
ASP.NET Javascript:
<script type="text/javascript">
var isCrawler = <%=HttpContext.Current.Request.Browser.Crawler.ToString().ToLower() %>
</script>
The problem of this approach is that it is not 100% reliable against unidentified or masked crawlers but maybe it is useful in your case.
After that, I had to find a way to distinguish between automated robots (crawlers, screen scrapers, etc.) and humans and I realised that the solution required some kind of interactivity such as clicking on a button. Well, some of the crawlers do process javascript and it is very obvious they would use the onclick event of a button element but not if it is a non interactive element such as a div. The following is the HTML / Javascript code I used in my web application www.so-much-to-do.com to implement this feature:
<div
class="all rndCorner"
style="cursor:pointer;border:3;border-style:groove;text-align:center;font-size:medium;font-weight:bold"
onclick="$TodoApp.$AddSampleTree()">
Please click here to create your own set of sample tasks to do
</div>
This approach has been working impeccably until now, although crawlers could be changed to be even more clever, maybe after reading this article :D

Resources