I need to keep a JSON file in the extension's web_accessible_resources so that it can be read by a content script through a synchronous XHR (the synchronous part is important, that's why I'm using a XHR).
However this file is supposed to reflect actions the user takes through the extension's interface, so when the user changes something there, the JSON file is rewritten by the background page (this can happen asynchronously). This way, next time the content script reads the file, it will be up to date.
Is there any way for an extension to modify a file that's listed under its web_accessible_resources?
Alternatively, as a last resource, it would be okay to make the extension open the file in a text editor and have the user directly edit it, but I'm afraid that would make Chrome assume the extension is getting compromised and disable it.
It's not possible to modify the contents of a file in the extension.
What you can do in this situation is to employ chrome.storage.onChanged event.
Your background page updates the information in chrome.storage.
This triggers chrome.storage.onChanged in the content script. You react to it by saving a local copy of the data. You don't even need to query the storage: new data is available in the event.
You access the local copy of the data synchronously.
This does not address the issue of having the data when the content script just starts executing, since you have to populate it initially asynchronously. But a synchronous XHR is a very clunky idea.
Some more ideas are covered here. Any of them are pretty convoluted hacks though, and Chrome's official position is "won't happen".
P.S. And just in case someone comes to this question really seeking variable response to an XHR, one can use chrome.webRequest API to redirect to a data: URI containing the data; the catch is that the URI itself must be constructed / available synchronously.
I dont think this is possible, since this is why there is a fileSystem API. I dont know your special use case, but isnt there a possibility of loading the file once the extension starts? In most cases the loading should be done before the user can even interact.
Related
I am creating a chrome extension that requires an HTTP Get Request API call whenever a new page loads. My extension then inserts an IFrame in the web page, to which I would like to provide the data from the API call. I have devised two different ways of doing this. I have been able to get both ways to work, however, I am wondering which is more advisable.
After the content script injects the iframe it makes a call to a background script. In the background script, we fetch the data and do message passing with the postMessage function to send the data to the IFrame. The data is then received by a script inside the IFrame and the data is loaded.
After the content script injects the iframe a script runs inside the IFrame that fetches the data. This same script then loads the data.
Or if there are any other methods, I would be grateful for any recommendations. My logic as of now comparing the two methods I have described is that the first method has advantages of conducting the API calls from the backgorund script, while the second method has the advantage of not requireing a large amount of communication between various scripts.
Is either of these methods superior? Thank you for the advice.
Any extension page or frame that has a chrome-extension:// URL has equal rights. It includes iframes that you insert in web pages with src pointing to an html file from your extension exposed via web_accessible_resources in manifest.json.
It means there are no inherent restrictions or preferred methods.
It only depends on the life cycle of data.
When it would make sense to make the request in the background page:
to cache it in a variable/object if you have a persistent background page for whatever reason;
to avoid interruption of the request due to the tab being closed or navigated away by the user or the main document's script;
to transform the data using some library that you load in the background script and don't want to load it in the UI page/frame for whatever reason e.g. it's slow to load.
any other reason.
As for sharing between pages it should be fast even with messaging unless your data exceeds 64MB message size limit in which case you would have to use Blob URLs or directly access the variable via getBackgroundPage that returns the window object of the background script. There's also BroadcastChannel API that should be able to work between all chrome-extension:// page or frames of an extension and in Chrome it should be much faster than messaging thanks to using the structured cloning algorithm instead of JSON stringify/parsing used by messaging internally.
As a rule of thumb for any performance-related concerns: use devtools performance profiler.
I have a program where the user does some actions (i.e. clicking on several buttons). I want to record their clicks and the buttons that they click to allow the user to then download a text file with a record of their clicks when they click a separate "download" button. I looked at the File-system APIs for HTML 5, but they seemed to not have cross-browser support. I would ideally like to have this entire file generation and download scheme be entirely client-side, but I am open to server-side ideas as well.
TL;DR: Essentially I'm looking for an equivalent to Java's FileWriter, FileReader, ObjectOutputStream, and ObjectInputStream within Vanilla JS or jQuery (would like to stay away from php, but I'll use it as a last option).
Also, why don't all browsers support the filesystem api? (I'm guessing that it would make MSWord and Pages go out of business with all the open source clientside text editors that could come out.)
Unfortunately the HTML5-File-system is no longer a part of the spec, long story short FF refused to implement because they claimed everything you could do in the File-System API was doable in the HTML5 Indexeddb (which was mostly true). Please see this blog post for more on why FF didn't implement. I do not know IE's story. (I may have exagerated why FireFox didn't implement, I'm still bummed because you cannot actually do everything in indexeddb that you can do in the noew "Chrome File-system API")
Typically if two of those three browsers implement a spec, it stays in the spec. Otherwise that spec gets orphaned. However, I'm fairly certain a large reason the file-system api didn't take off is because of the IndexedDB API (caniuse IndexedDB) really took off when both specs were introduced. If you want cross browser support, check this api out.
That all said if you are still set on the file-system api some developers wrote a nice wrapper around the IndexedDB, the File-system api wouldn't actually supply you with a stream anyway. You would have to keep appending events to a given file given a fileWriter object. you'd then have to read the entire file and send to the server via an ajax request and then downloaded from the server once successfully uploaded.
The better route would be to use the IndexedDB apiwhich as stated on developer.mozilla
Open a database.
Create an object store in upgrading database.
Start a transaction and make a request to do some database operation, like adding or retrieving data.
Wait for the operation to complete by listening to the right kind of DOM event.
Do something
with the results (which can be found on the request object).
Here are a couple tutorials on the IndexedDB.
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB
http://www.html5rocks.com/en/tutorials/indexeddb/todo/
As for giving the user that file, as mentioned briefly before you would have to upload the file to the server and download upon the "download" request. Unfortunately you have to trick the user into giving them the data already on their machine. Anyway, hope this all helps.
I'm using google chrome.
These images are lagging the browser, so I need away to access it and clean it all.
You are asking how to solve the wrong problem. If your high-frequency ajax calls return images that they don't need, then you are making bad ajax calls. Deleting the files would be treating a symptom when you should be treating the cause.
Find a way to not download them in the first place. The result of an ajax call can be scoped, filtered, or even parsed manually. There's no reason to allow the full result of your ajax call to store these extra resources that you don't want. If you want to know specifically how to do that filtering, you'll need to post the code that generates your ajax calls.
_generated_background_page.html is a file created by an extension installed into Google Chrome. If you are working on a website (not a Chrome Extension), these files are not delivered by that site and can be safely ignored.
Also... a handful of images won't cause any meaningful lag on a modern browser.
I'm trying to build a sample bookmarklet to grab current webpage source code and pass it to a validator. Validator is not a an online website, but a folder with bunch of javascript and html files. I'm trying to open file:///C:/Users/Electrifyings/Desktop/Validator/Main.html file with the help of javascript bookmarklet code and put the source code in the textarea in the newly opened window, but it is not working for some reasons that I'm not aware of.
Here is the sample code with algorithm:
javascript:(function(){var t = document.body.innerHTML;window.open('file:///C:/Users/RandomHero/Desktop/test.html',_self);document.getElementById("validator_textarea")=t;})()
Here are the steps:
Grab current web page source code in a variable.
Open locally stored HTML web page in current or new window or new tab (either way is fine with me, but no luck)
Put the source code from the variable into the validator textarea of the newly opened HTML file.
I have tried above code with a lot of variations, but got stuck on the part where it opens the new window. Either it's not opening the new window at all or it is opening blank window without loading the file.
Would love to get some help with this issue, thanks a lot.
Oh and btw,
Windows 7 x64, Tried IE, Firefox and Chrome. All latest and stable builds. I guess it's not a browser side issues, but something related to javascript code not opening the URI with file:/// protocol. Let me know if any more details are needed. :)
You wouldn't want a webpage you visit to be able to open up file://c:/Program Files/Quicken/YourSensitiveTaxInfo right? Because then if you make a mistake and go to a "bad" website (either a sleazy one or a good one that's been compromised by hackers), evil people on the intarweb would suddenly have access to your private info. That would suck.
Browser makers know this, and for that reason they put VERY strict limits to prevent Javascript code from accessing files on a user's local computer. This is what is getting in the way of your plan.
Solutions?
build the whole validator in to the bookmarklet (not likely to work unless it's really small)
put your validator code up on the web somewhere
write a plug-in (because the user has to choose to install a plug-in, they get much more freedom than webpages ... even though for Firefox, Chrome, etc. plug-ins are basically just Javascript)
* * Edit * *
Extra bonus solution, if you don't limit yourself to a purely-client-side implementation:
Have your bookmarklet add a normal (HTML) form to the page.
Also add an iframe to the page (it's ok if you hide it with CSS styling)
Set the form's target attribute to point to the iframe. This will make it so that, when the user submits the form and the server replies back to that submission, the server's reply will go to the (hidden) iframe, instead of replacing the page as it normally would.
Add a file input to your form - you won't be able to access the file within that input using Javascript, but that's ok because your server will be doing the accessing, not your bookmarklet.
Write a server-side script which takes the form submissions, reads the file that came with it, and then parrots that file back as the response. In other words, you'll have a URL that you can POST to, and when it sees a file in the POST's contents, it will respond back with the contents of that file.
Now that you've got all that the user can pick their validator file using the file input, upload it to your server, your server will respond back with the file it just got, and that file will appear as the contents of the iframe.
And now that you finally have the file that you worked so hard to get (inside your iframe) you can do $('#thatIframe').html() and viola, you have access to your file. You can save the current page's source and then replace the whole page with that uploaded file (and then pass the saved page source back to the new validator page), or you can do whatever else you want with the contents of the uploaded validator file.
Of course, if the file doesn't vary from computer to computer, you can make all of that much simpler by just having a server that sends the validator file back; this could be a pure Apache server with no logic whatsoever, as all it would have to do is serve a static file.
Either way though, if you go with this approach and your new file upload script is not on the same server as your starting webpage, you will have a new security problem: cross-domain script limitations. However, these limitations are much less strict than local file access ones, so there are ways to work around them (JSONP, cross-site policy files, etc.). There are already tons of great Stack Overflow posts explaining these techniques, so I won't bother repeating them here.
Hope that helps.
Is there any client-side script that would be able to make changes to a file on the hosts computer? (Intention stated below)
I am creating a packaged app for chrome which can show some online data, and make it available even when offline.
There is a certain thing, for e.g. 'a webpage' i want to show/store (but i cannot get/read its contents due to it being on different origin). To show when online, i can use iframe, but am unable to preserve it for offline.
So i thought i could make an appcache (manifest within the application package) which will cache the file, and on press of an update button a script would run which would make some change to the manifest which would force the cached resource to be reloaded.
I searched a lot, but no results.
Any suggestions as to how it can be done. Or any other way to get it to work?
I don't think so. This could be a huge security problem if it existed.
If you had to, you could send an ajax request to the server to create a file it creates with the current prices, and add it to the appcache file.
Here is a link to another SO quesitob that has a list of APIs you could use to get your stock price.
Webservice to get stock quotes?