I am trying to send a ajax request to a server inside a google chrome extension. I am using angular with it too and the code is inside the controller. The request works fine generally, but when I have the the DevTools open it throws an error. This is the relevant part of the code:
$scope.sendLink = function (){
chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
var url = tabs[0].url;
var date = new Date();
var xPost = new XMLHttpRequest();
xPost.open("POST", **URL HERE*",true);
xPost.setRequestHeader("Content-type", "application/json");
xPost.send(JSON.stringify({"name":$scope.name,"url":url,"date":date}));
});
}
When I hit inspect element on the extension, and then do the request, the tabs array come back as empty. It works fine if the devTools window is closed. I can't figure out why that is the case. Any explanation would be appreciated!
You could have changed the javascript engine behavior via chrome-dev-tools. This would get activated only when the dev-tools are open.
For instance, once I found that a mate of mine had turned-off javascript using the chrome-dev-tools. His app wasn't executing when the chrome-dev-tools were open...
Related
I have developed a Chrome Extension and it's mostly compatible to firefox web-extensions API. Just one problem:
In Chrome Extension i have popup.js and background.js. User click's a button, popup.js does chrome.sendMessage to background.js where data is received and afterwards (popup.html may be closed meanwhile) i just call in background.js:
newWin = window.open("about:blank", "Document Query", "width=800,height=500");
newWin.document.open();
newWin.document.write('<html><body><pre>' + documentJson + '</pre></body></html>');
// newWin.document.close();
so that works fine in Chrome extension but not in firefox. I read here (https://javascript.info/popup-windows) that for safety reasons firefox will only open with a "button click event". And if i move above code to popup.js, inside button-click-evenListener, it will open this way (but i dont have the data prepared yet, thats really not what i want)
So i tried everything i found but i dont get the chrome.tabs.executeScript running. Here is my code with comments:
popup.js
// working in firefox and chrome (popup.js)
const newWin = window.open("about:blank", "hello", "width=200,height=200");
newWin.document.write("Hello, world!");
// not working firefox: id's match, he enters function (newWindow) but document.write doing nothing (but no error in log)
// not working chrome: doesnt even enter "function (newWindow)""
chrome.windows.create({
type: 'popup',
url: "output.html"
}, function (newWindow) {
console.log(newWindow);
console.log(newWindow.id);
chrome.tabs.executeScript(newWindow.tabs[0].id, {
code: 'document.write("hello world");'
});
});
background.js
(created local output.html and gave several permissions in Manifest.json - tabs, activeTab, output.html, , about:blank)
// opening but executeScript not working in firefox: Unchecked lastError value: Error: The operation is insecure.
// opening but executeScript not working in chrome: Unchecked runtime.lastError: Cannot access contents of url "chrome-extension://plhphckppghaijagdmghdnjpilpdidkh/output.html". Extension manifest must request permission to access this host
chrome.tabs.create({
// type: 'popup',
url: "output.html"
}, function (newWindow) {
console.log(newWindow);
console.log(newWindow.id);
chrome.tabs.executeScript(newWindow.id, {
code: 'document.write("hello world");'
});
});
How can I get the data into the new window/popup from background.js - i can open an empty page from there, so it's only about getting executeScript() running
Thanks to #wOxxOm for pointing me to a data URI to transport the json document into the browser from background.js.
While searching for a javascript method to build a data URI i found this thread, with the suggestion to create a Blob :
https://stackoverflow.com/a/57243399/13292573
So my solution is this:
background.js
var documentJson = JSON.stringify(documents, null, 2)
let a = URL.createObjectURL(new Blob([documentJson]))
chrome.windows.create({
type: 'popup',
url: a
});
I would like to write a simple script to open a Website and call a function that is part of a linked .js-file.
To be more precise, I want to open a SharePoint, invoke the function that is used to open the folder in windows explorer and close the website again.
For some reason, I may not open the folder directly in explorer unless I had it done this way at least once during the active windows session...
How may I do this?
So far, I tried the following:
var IE = new ActiveXObject("InternetExplorer.Application");
var WSH = new ActiveXObject("WScript.Shell");
IE.visible = true;
IE.navigate("https://mysharepoint.com/Folder");
WSH.PopUp("Click to fire function");
//the following line throws an error, because the function is unknown...
IE.Document.defaultView.setTimeout(NavigateHttpFolder, 0, "https://mysharepoint.com/Folder", "_blank");
//the following line does not throw an error, but nothing happens either..
IE.Document.defaultView.setTimeout(function(){NavigateHttpFolder("https://mysharepoint.com/Folder", "_blank");}, 0);
However, when I open my Sharepoint and type the following line into the addressbar it does exactly what I want to achieve and it opens the folder...
javascript:NavigateHttpFolder("https://mysharepoint.com/Folder", "_blank");
Could you please help me? I simply cannot find a way to get this to work.
UPDATE: Now it worked suddenly! I tried it the following way before but it didn't do anything until now (???)...
IE.Navigate('javascript:NavigateHttpFolder("https://mysharepoint.com/Folder", "_blank");');
You can include script with path to external website
<script type="text/javascript" src="http://www.external.com/script.js"></script>
I am working on a chrome extension, and I need information about the active tab (when I say "active", I mean the tab that I am looking at in the current window that is focused).
Using the chrome.tabs api, I should be able to do something like the following to get what I want:
function getActiveTab() {
var activeTabInfo = {"currentWindow": true, "active" : true};
return chrome.tabs.query(activeTabInfo,function (tabs) {
return tabs[0];
});
}
However, when I log the length of tabs within the callback, I'm getting a length of 0. I modeled this snippet after How to fetch URL of current Tab in my chrome extension using javascript, but can't seem to get it to work.
Any thoughts?
I have a native app which has to interact with a website. It has been working normally up to iOS 9, but with iOS 10, the Javascript code inside the web app is no longer valid.
Here is an example of the JS code I use on the onClick event of a button, which as mentioned worked like a charm before iOS10.
function DoSomething()
{
var iframe = document.createElement("IFRAME");
var url='codeToBeUsed://id=1230';
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
when I debug the app on Xcode, the request variable which normally contained the content of the "url" variable on the example provided, now returns a blank value...
<NSMutableURLRequest: 0x170011070> { URL: about:blank }
I even tested placing a alert('click'); but it didn't work either. Does anybody know how to solve this issue?
Using a code close to yours (I pass a stringified json in the src), I also got an embarassing 'about;blank' in the request.
It seems iOs10 has some new restrictions on what you pass to iframe 'src'. I found it requires a valid url to trigger properly the request.
Try to use :
var url='codeToBeUsed://?id=1230';
Edit : or encode URI...
My question regards the Apps CSP https://developer.mozilla.org/en-US/Apps/CSP
Here it says that all the remote script, inline script, javascript URIs, and other security issues won't work on a Firefox OS app.
So, I tried to download a script that is necessary for my app (Flurry and Ad service) and neither would work on the device. The way I made the call was with AJAX, that way I would avoid the remote and inline scripting that both scripts ment. In the simulator works perfectly, but on the device the ads never show and the Flurry session never starts.
Here is the part of my code where I make the AJAX call for Flurry:
$.ajax({
url: 'https://cdn.flurry.com/js/flurry.js',
dataType: "script",
xhrFields: {
mozSystem: true
},
success: function(msg){
console && console.log("Script de Flurry: luego de la descarga en AJAX "+msg);
flurryLibrary = true;
FlurryAgent.startSession("7ZFX9Z4CVT66KJBVP7CF");
},
error:function(object,status,errortxt){
console && console.log("The script wasn't downloaded as text. The error:" +errortxt);
flurryLibrary = false;
},
always: function(object,status,errortxt){
console && console.log("The script may or may not be downloaded or executed. The error could be:" +errortxt);
}
});
In my app I use the systemXHR permission and make the calls for other websites using this line:
request = new XMLHttpRequest({ mozSystem: true });
Wich is the same as using the xhrFields{mozSystem:true} in the AJAX call.
I believe it's not a cross domain problem because in the rest of my app I make calls for xml files that are not in my domain, and the calls are returned succesfully.
So, my question is, can a Firefox OS app execute scripts that are downloaded via AJAX? Is there a way to get around this problem?
Thank you for your time.
PS: I forgot to add that my app is privileged, just in case you ask
I believe that is a security feature and the short answer to your question would be NO. To quote the CSP doc that you linked to yourself:
You cannot point a at a remote JavaScript file. This means that all JS files that you reference must be included in your app's package.
If you load a JS file using ajax from a remote server, that JS is not included in your app package. You should be careful to obey CSP restrictions. It is possible to get many things working in the simulator or even the phone while developing without fully complying to CSP, but that does not mean it is OK. When you submit your app in future to any credible marketplace (such as Firefox Marketplace), it will be reviewed carefully to make sure it does not violate CSP restrictions. As a general rule of thumb, I would say any attempt at dynamically evaluating JS code will be a security risk and most likely banned by CSP regulations.
First, I'll point out that your two examples are not equivalent.
$.ajax({
xhrFields: {
mozSystem: true
},
});
Is the same as
request = new XMLHttpRequest();
request.mozSystem = true;
which is not the same as
request = new XMLHttpRequest({ mozSystem: true });
Instead, we can follow the advice in the linked bug report and run the following at application load time:
$.ajaxSetup( {
xhr: function() {
return new window.XMLHttpRequest( {
mozSystem: true
} );
}
} );
This alone should fix your problem. However, if it doesn't work, then the next workaround here is to fetch the script resource as plain text and then load that text content as a script.
However, inline scripts and data: URLs are off-limits for privileged Firefox OS apps. We might still accomplish this goal through a blob: URL, however:
window.URL = window.URL || window.webkitURL;
var request = new XMLHttpRequest({ mozSystem: true });
request.open("GET", "https://cdn.flurry.com/js/flurry.js");
// when the Ajax request resolves, load content into a <script> tag
request.addEventListener("load", function() {
// make a new blob whose content is the script
var blob = new Blob([request.textContent], {type: 'text/javascript'});
var script = document.createElement('script');
script.src = window.URL.createObjectURL(blob);
// after the script finishes, do something else
script.addEventListener("load", function() {
flurryLibrary = true;
FlurryAgent.startSession("7ZFX9Z4CVT66KJBVP7CF");
});
document.body.appendChild(script);
});
However, if the script itself does something not allowed by the CSP, then you're definitely out of luck.
You must use mozSystem and mozAnon properties, example:
var xMLHttpRequest = new XMLHttpRequest({
mozAnon: true,
mozSystem: true
});
Its a shame this is a problem, I was hoping on getting loadScript working, as firefoxOS is an environment, and in my app all the application code is HTML5 and local, the current rule is all the scripts need to be loaded in memory in one shot, unless you url load a full page, which means you can not have a persisten wrapper around the site, and ajax inthe pages with assosiated scripts when needed. you would have thought that firefox would have enabled local lazy load for scripts at least. works in chrome, but not in firefox.