Chrome Extension / App Settings Javascript - javascript

So I'm trying to think of a method to get a "local" file not from the user but from the Google Chrome App or Extension which ever it may be since I am building both. Basically, it'll be my Settings JSON and I need access to it through my Options Page, like to have access to it via my content scripts but it's ok, and I need access to it via my Background page.
Sample Settings.json
{
"defaultResults": "all",
"view":"full",
"results":"cur",
"count":"5",
"omni":{
"h8":{
"title":"Hello World",
"url":"www.someurl.com"
}
}
}
So does anyone have any real options for this. I'm not positive if Google has already implemented a native function for this such as chrome.getAppFile("file URL"); or something of that matter. I'd rather not use Ajax inside my app for this file. And I'd rather not use it everywhere. So hopefully, someone here will have a reasonable idea how I should go about this.

You can do this in 2 ways, as described in this answer.
By assigning your JSON object to a variable, saving the script as settings.js, and including it in your background page, as follows:
settings.js looks as follows:
var settings = {"param":value,...}; //Your JSON object
then, in your background page:
<script src="settings.js"></script>
By making an AJAX call to your settings.json from your background page:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
xhr.open("GET", chrome.extension.getURL('/config_resources/config.json'), true);
xhr.send();
As discussed in the comments, you cannot use FileSystem API in chrome extensions. Only chrome apps have access to it. Either way, the FileSystem API works in a sandboxed zone, so I'm not sure if you can write to files packed with the extension.

Related

Chrome edit 3rd party script [duplicate]

I would like to override a javascript file with my own version of the similar javascript file in chrome.
Let me explain:
Lets say a site 'http://example.com' calls 'http://example.com/script/somescript.js'.
What I would like to do is override the file 'http://example.com/script/somescript.js' with my own version located at 'http://localhost/script/somescript.js'.
I need to effectively modify a function in the original Javascript file.
With Chrome 65 this has become trivial.
Using local overrides – Chrome 65
What is it?
It is a new feature that allows us to override a websites code/css with a local copy that is persisted across sessions. Once you override a file it shall remain until you remove the override.
How to set it up?
Open the Sources panel.
Open the Overrides tab.
Open overrides tab
Click Setup Overrides.
Select which directory you want to save your changes to.
At the top of your viewport, click Allow to give DevTools read and write access to the directory.
Make your changes.
After you add a folder you can switch to the network tab and right click on any file and select “Save for overrides”. I have already overridden scripts.js so it shows with a “blue dot”.
There are plugins and tools in Chrome for these purposes:
Chrome's DevTools, tab Local Overrides (supported from Chrome 65)
Requestly
Resource Override
You might also want to use Tamper, which is a mitmproxy based devtools extension that lets you edit remote files locally and serve them directly to Chrome. (but it's more headache to install and use it)
Choose the one which is easier to use for you.
You can create a chrome extension yourself. It is surprisingly easy and takes only a few minutes if you use a tool like yeoman chrome extension. Create a new directory and run the generator
yo chrome-extension
Enter a name for your extension and a short description. Select Page Action and that you want to use Content Scripts. You can ignore other options - follow this excellent guide if you come in doubt, but it is really straight forward.
? What would you like to call this extension? insert-script
? How would you like to describe this extension? replace a function with another function
? Would you like to use UI Action? Page Action
? Would you like more UI Features? Content Scripts
? Would you like to set permissions?
..etc. Now you have a directory structure like this
app
bower_components
images
_locales
scripts.babel
background.js
chromereload.js
contentscript.js
You cannot replace an existing loaded remote script with another script, since the script already is loaded into the DOM. But you can insert a new script at the end of body which overrides the function you want to replace. Functions is variables, if you add a new function to the document with the same name as an existing function, the new function will be executed instead of the old, exactly as if you declared a new variable with the same name as an existing variable. Now open and edit contentscript.js :
'use strict';
console.log('\'Allo \'Allo! Content script');
The code could look like this
'use strict';
var code = `
function foo() {
alert('foo');
}
`;
var script = document.createElement('script');
script.textContent = code;
document.body.appendChild(script);
Notice the template literal. We need to insert the code as a string, but with backticks it is more readable. Replace foo() with the function you want to override.
There is no need for deployment or bundling. You can install your extension right away from the path where you runned the generator
go to chrome://extensions
check developer mode
click upload unpacked extension
select manifest.json from your path
after that you just have to hit reload on the extensions page when you have made changes to contentscript.js.
you can load your file into the page by adding (or executing in the console) this script.
window.onload = function () {
var script = document.createElement('script');
script.src = '//localhost/your/script';
script.onload = function() {
console.log('your script have been loaded');
}
document.body.appendChild(script);
}
If the file that you want to override contains global functions/variables will be override with the new version in your file or if the elements that you want to override are namespaced just follow the path (e.g My.namespace.method = myNewMethod)
According to dharam's answer above,Resource Override works.
For people who doesn't have access to Chrome store,you can download the source here:
https://github.com/kylepaulsen/ResourceOverride
in Chrome,get into chrome://extensions/ ,enable developer mode,then load the extracted source root directory(which contains the file manifest.json) into Chrome.
tested for Chrome 73.0.3683.86 on Windows 10 .I can't post anything on StackOverflow before because https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js is blocked.Then in the settings of ResourceOverride,I map it to https://localhost/jquery-1.12.4.min.js and it finally works.
I run an ASP.NET Core 2.1 project with SSL enabled and localhost certificate enabled to serve jquery-1.12.4.min.js from local disk.
In the launchSettings.json,there is
"applicationUrl": "https://localhost:443;http://localhost:80",
in the Kestral profile(not IIS profile).

How can I get the HTML of a site as a variable in Javascript or jQuery?

I'm trying to get 10 million digits of pi from this site to use as a variable in Javascript. I'd like to get the HTML from the site with a simple command instead of hardcoding it. I'm using Codepen so I can't just copy and paste the text (Codepen doesn't allow so many characters). Can you help me get the HTML?
Any help is greatly appreciated!
Copying and pasting those digits would take hours
Shouldn't it be as simple as ctrl+a then copy? Then just trim the top and bottom unnecessary parts? Anyway here's a solution you could try.
Open the website
Open the Developer Tools [ Ctrl+Shift+i ], I'm on Google Chrome on a linux build
Copy & Paste the code below into the console
Profit, 10MB file
saveToFile(document.querySelector('center').textContent);
function saveToFile(string){
var blob = new Blob([string], {type:'application/text'});
var url = URL.createObjectURL(blob);
var hiddenAnchorElem = document.createElement('a');
applyAttrs.call(hiddenAnchorElem, {
href: url,
target: '_blank',
download: 'pi.text'
});
hiddenAnchorElem.click();
function applyAttrs( attrs ){
var keys = Object.keys;
keys(attrs).forEach( attr => {
this[attr] = attrs[attr];
});
}
}
You could use AJAX, if it's on the same server as your website, or if CORS is allowed by the site (which is unfortunately not likely).
You'll probably want to write server side code that pulls in the HTML of the page you would like to request, and prints it out - a proxy of sorts - and use the URL of that page rather than the actual page you are trying to get the HTML for.
Here's an example of how AJAX can be used: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest. In that example, the HTML of the page would be stored in this.responseText in the callback handler for the AJAX call's onload event.
If you're just using this locally, though, you may be able to get around the Cross Origin Request Policy.
If you run Chrome from your Command Prompt using:
Chrome.exe --disable-web-security
...from the directory in which Chrome is installed, you'll be able to use AJAX to get the contents of the page without any server-side code.

Local javascript cannot open local file

Please tell me, why local javascript cannot open a local file?
I'm trying to create a simple javascript/html app that shall run on the local machine from local filesystem. This app is trying to read the configuration file (json) using different methods, but gets the following errors (Chrome):
In case of XMLHttpRequest, method open("GET", filename, true) throws an exception:
XMLHttpRequest cannot load file:///bla-bla-bla. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
In case of document.createElement("iframe").src=filename I have another exception:
VM596:1 Uncaught DOMException: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "null" from accessing a cross-origin frame."
In case of var f=new File([], filename, { type: "text/plain" }); I've got the File object with the zero size and no errors at all. FileReader returns an empty result then.
So, my questions are:
Why is it "cross-origin"? These files are stored in the same directory!
And how could I open the local file from the same origin/directory I run the script?
Please help.
P.S.: Yes, I know about --allow-file-access-from-files but I need to run this by customers.
Why is it "cross-origin"? These files are stored in the same directory!
Because Chrome considers all file:// URLs to be cross-origin to each other.
And how could I open the local file from the same origin/directory I run the script?
From Chrome? You don't. Not unless you disable CORS entirely with a command-line option (which is a bad idea, as it's trivially easy to forget you've set that command-line option and go surf the web, leaving yourself wide open to exploits cashing in on the fact you've disabled web security).
Other browsers may treat origin null differently.
Instead, run a local web server and make the files available via the local web server. Then you can access them because it'll be a same-origin http URL, not a file URL. Or use any of the dozen or so frameworks that let you write apps in JavaScript (rather than using the browser). Or a simple NodeJS script serving the files (it's about 10 lines long). Etc.
What you can do to read your .json file, is to declare it a .js.
data.js
var data = `{"value1": 10, "value2": "hello"}`
index.html
<script src="data.js"></script>
<script>
console.log(JSON.parse(data))
</script>
This will print
Object {value1: 10, value2: "hello"}
Both of them have to be in the same directory, otherwise you've to change the import of data.js.
A little late for this party, but I had the same issue and this was how I got around the problem
Create a js template such as this:
template.js
(function(global, factory) {
"use strict";
factory(global);
})(typeof window !== "undefined" ? window : this, function(window) {
"use strict";
var myObjectJson = '<JSONREPLACE>';
var myObject = JSON.parse(myObjectJson);
window.myObject = myObject;
});
Then, have your json replace the tag either by your program that could generate the exported js itself, or create a batch script file that does that for you. I'm using C# so I just build the template directly from there. If the language you're working on is half-decent, you should be able to generate and export your file.
Make sure you use a minified json string.
Then you use your generated file just like you'd use jQuery
<script src="generated.js"></script>
and access your object with
window.myObject;
It's slightly more complicated to set-up, but once you do, you completely remove the cross-origin issue.

Page loading takes time

My website uses ajax to fetch and display data often..Everytime a request is made , it displays data fast but keep on loading. I'm unable to click on anything else, as once the psge is fully loaded, only then I can interact with the page.
I checked the console and I would like to understand what causes the following :
As I clicked on one of the links marked in red above, I got this in the console too.I don't have any link to facebook share or like button. I would like to understand what causes this error , please.
(function () {
if (window.g_clrDimensionsSent) return;
window.g_clrDimensionsSent = true;
var data = new FormData();
data.append('windowWidth', window.innerWidth);
data.append('windowHeight', window.innerHeight);
data.append('headHtml', window.document.head.outerHTML);
data.append('bodyHtml', window.document.body.outerHTML);
var xhr = new XMLHttpRequest();
xhr.open('POST', document.location.protocol + '//__fake__.com');
xhr.send(data);
})()
It looks like you are connecting from your local machine and not the website for which your Facebook page is set up. Have you checked the settings of your Facebook app?
Usually you should use your hosts file to rather mimmick your live url, or you must set the Canvas, Public etc URLs as "localhost" and not your live website.
As for the parts in RED, your site is making a post to "fake.com"... which is most likely malware in your browser, unless you specifically coded calls to post to that URL?
Run malware bytes to confirm, or disable all your plugins in your browser. The "VM" part means its the browser throwing the error, and not the website. Do a check to see if you also get those errors on other pages.

Read a text file

I have looked everywhere and surprisingly can't find a good solution to this! I've got the following code that is supposed to read a text file and display it's contents. But it's not reading, for some reason. Am I doing something wrong?
FTR, I can't use PHP for this. It's gotta be Javascript.
var txtFile = new XMLHttpRequest();
txtFile.open("GET", "http://www.mysite.com/todaysTrivia.txt", true);
txtFile.send(null);
txtFile.onreadystatechange = function() {
if (txtFile.readyState == 4) { // Makes sure the document is ready to parse.
alert(txtFile.responseText+" - "+txtFile.status);
//if (txtFile.status === 200) { // Makes sure it's found the file.
var doc = document.getElementById("Trivia-Widget");
if (doc) {
doc.innerHTML = txtFile.responseText ;
}
//}
}
txtFile.send(null);
}
Any good ideas what I'm doing wrong? It just keeps givimg me a zero status.
EDIT: I guess it would be a good idea to explain why I need this code. It's basically a widget that other folks can put on their own websites that grabs a line of text from my website and displays it on theirs. The problem is that it really can't be server-side since I've got zero control over everyone else's sites that use this.
If this is cross domain, you won't be able to do this with an xmlhttprequest due to the same origin policy.
This exmaple contains jQuery code.
var text;
$.get( "proxy.php", function(data) {
text = data.responseText;
});
Then in proxy.php:
<?php
header('Content-type: application/xml');
$daurl = 'http://www.mysite.com/todaysTrivia.txt';
$handle = fopen($daurl, "r");
if ($handle) {
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
echo $buffer;
}
fclose($handle);
}
Example taken from here:
http://jquery-howto.blogspot.com/2009/04/cross-domain-ajax-querying-with-jquery.html
As explained before, xmlhttp is designed for forbid cross domain requests for security issues. But nothing prevents you from doing this on your server in PHP.
Another example can be found here: http://usejquery.com/posts/9/the-jquery-cross-domain-ajax-guide
Your problem could be with the fact that you can only request XML data from the same domain via Javascript. This is the biggest issue with AJAX calls - if the text file is on another server, you can't get it via AJAX. If it's on the same server, make your request using a relative URL (no http://).
EDIT
Now that I know what you're trying to accomplish ... my recommendation would be to use an iFrame. Build the system on your server using server-side code and allow remote sites to embed an iFrame to display the output on their own sites. NetworkedBlogs uses this for displaying Facebook features on remote sites. iGoogle uses it extensively with their various Apps and Gadgets. It's a fairly tried-and-true method.
The advantage of using an iFrame is that you'll still have control over most of the content of the widget, but you can give end-users control over the styling (just have your iFrame application accept arguments via query variables to change colors, positions, and sizes).
Assuming the AJAX stuff is right (which I haven't confirmed): You say you can't use PHP for this - if you just mean you need it to use javascript asynchronously but can still use server code in some places, what about using PHP (or any server-side language) to do the actual work and return it to the page through AJAX/javascript - this would solve the problem Alex brings up.
So instead of getting from mysite.com/something.txt from javascript, get it from SomeAjaxHelper.php (or aspx or whatever).
For cross domain, you would have to use dynamic script tags to fetch data asynchronously. The todaysTrivia file would be a .js file that stores the data as JSON. Google for "dynamic script tags cross domain" if you want to use this technique.

Categories