Problem with WebExtensions: second injected script doesn't see the first one - javascript

I need to create Firefox WebExtension that should use Amazon AWS SDK for Javascript. So to use its functions I try to inject such scripts into the loaded page:
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.485.0.min.js"></script>
<script>My code using AWS functions</script>
When I just create such page it works fine:
<html>
<body>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.485.0.min.js">
<script">console.log(AWS)</script>
</body>
</html>
Then I try to inject this code to the loaded page with WebExtensions content script like:
var s1 = document.createElement('script');
s1.src = "https://sdk.amazonaws.com/js/aws-sdk-2.485.0.min.js";
document.body.appendChild(s1);
var s2 = document.createElement('script');
s2.textContent = "console.log(AWS);";
document.body.appendChild(s2);
The scripts are successfully injected but in this case the second script returns the error: "AWS is not defined".
How can I fix this?
Thanks :)

Related

GPT Passbacks without document.write

I'm trying to use the passback functionality of the gpts without booking it directly in dfp. Unluckily until now without success. If I'm booking this snippet
<script type='text/javascript' src='http://www.googletagservices.com/tag/js/gpt.js'>
googletag.pubads().definePassback('/ID/AD_Unit', [728, 90]).setTargeting('key', ['value']).display();
</script>
everything is working properly. Then I tried following snippet:
<script type="text/javascript" src="http://www.url.de/to/gpt_ad.js"></script>
gpt_ad.js contains the snippet above with document.write wrapped. That is working too. Now I tried it with document.createElement instead of document.write. The code snippet is:
var tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = 'http://www.googletagservices.com/tag/js/gpt.js';
var code = 'googletag.pubads().definePassback(\'/ID/AD_UNIT\', [728, 90]).display();';
tag.appendChild(document.createTextNode(code));
var node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(tag, node);
Inserting worked but there are no ads showing. I'm a bit clueless. I also receive following error:
Failed to execute 'write' on 'Document': It isn't possible to write
into a document from an asynchronously-loaded external script unless
it is explicitly opened. > pubads_impl_75.js:195

Inject external javascript file out of time

I want to load an external javascript. This javascript contains source for an ad. I use a method of injection because the javascript needs the user IP. The javascript code to use is:
<html>
<head>
<script type="text/javascript">var userip;</script>
<script type="text/javascript" src="http://service.get.userip?var=userip"></script>
<script>
var url="http://example.com/abc?user_ip=" + userip;
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.src = url;
headID.appendChild(newScript);
</script>
</head>
</html>
I use a service javascript to get the IP of user ("http://service.get.userip?var=userip" in this example code). Then I added the user IP to the url where I download the javascript.
The javascript is inserted when it revised the web charged with developer mode browser but it doesn't work.
I think the problem is that the JavaScrip injection is slow and this is no time to charge properly.
In my tests I got a proper operation to put a alert before the end of the last script:
<script>
...
headID.appendChild(newScript);
alert("Script is Load!");
</script>
For this reason I think the problem is load time. I also try loops, sleep() and setTimeout(), but I do not reproduce the smooth running that I get with the alert().

Loading another script from a Javascript file but I can't access functions in the loaded script

I've been trying to load a file using the following code, in a file I've called InterpolatorTest.js:
include("scripts/ProceduralContentGeneration/NoiseGeneration/Interpolation/Interpolator.js");
var interpolator = new OneDimensionalInterpolatorTemplate();
This is the include code, which is loaded in the header of every page:
function include(scriptName) {
var script = document.createElement('script');
script.type = "text/javascript";
script.src = scriptName;
document.getElementsByTagName("head")[0].appendChild(script);
}
And this is the script I'm trying to include, Interpolator.js:
OneDimensionalInterpolatorTemplate = function() {
}
However, when I try to load the script, I get the following error:
Uncaught ReferenceError: OneDimensionalInterpolatorTemplate is not defined --- InterpolatorTest.js:3
It doesn't seem to be able to access the methods in the loaded script, but it doesn't give me a 404 error so I assume it's loading the script successfully. I've used this include script before with success.
This is the actual code for the page:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Page Title</title>
<script type="text/javascript" src="scripts/EssentialUtilities.js"></script>
</head>
<body>
<script type="text/javascript" src="scripts/ProceduralContentGeneration/NoiseGeneration/Interpolation/InterpolatorTest.js"></script>
</body>
</html>
I've been working on this for hours and I'm totally stumped. Anyone know what's wrong?
Edit: Thanks to the answer from Alberto Zaccagni, I got it working by installing jQuery and using this code snippet. The issue seems to be that Javascript loads files asynchronously, so I was attempting to call the method before it was loaded. AJAX has a synchronous loading method, so that eliminated the problem. :)
I think that what you're missing is the onload bit, have a look at this question: How do I include a JavaScript file in another JavaScript file?
I include the relevant snippet as reference:
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}

Page loading blocks by remote javascript

I am loading external javascript on my site through:
<script language="javascript" type="text/javascript">
document.write("<script src='http://remoteserver/banner.php?id=10&type=image&num=3&width=200'><\/script>");
</script>
Everything was fine, but today was a big timeout from the remote server and page loading on site was blocking.
Is there possibility to load javascript asynchronous or to load it after page loads?
I don't want page load interruption while remote server not working.
I know there are tag async in HTML5, but it's not working, i think because this script is more complex than javascript (its ending with ".php").
Also i know it's better to put javascript files before /body tag to prevent this problem, but it's not the best solution.
Do you know other solutions?
Sync script blocks the parser...
Incorrect Method:
<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
</script>
Async script will not block the rendering of your page:
Correct method:
<script type="text/javascript">
(function(){
var po = document.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = "https://apis.google.com/js/plusone.js";
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
</script>
Source: http://www.youtube.com/watch?feature=player_detailpage&v=Il4swGfTOSM&t=1607
You can easily do it by creating DOM nodes.
<script>
var scriptEl = document.createElement("script"); //Create a new "script" element.
scriptEl.src = "http://remoteserver/banner.php?id=10&type=image&num=3&width=200";
// ^ Set the source to whatever is needed.
document.body.appendChild(scriptEl);
// Append the script element at the bottom of the body.
</script>

how to: dynamically load google ajax api into chrome extension content script

I'm trying to make use of google's ajax apis in a chorme extension's "content script". On a regular html page, I would just do this:
<script src="http://www.google.com/jsapi"></script>
<script>
google.load("language", "1");
</script>
But since I'm trying to load the tranlation library dynamically from js code, I've tried:
script = document.createElement("script");
script.src = "http://www.google.com/jsapi";
script.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(script);
google.load('language','1')
but the last line throws the following error:
Uncaught TypeError: Object #<an Object> has no method 'load'
Funny enough, when i enter the same "google.load('language','1')" in chrome's js console, it works as intended...
I've also tried with jquery's .getScript() but the same problem persists...
Does anybody have any clue what might be the problem and how it could be solved?
Many thanks in advance!
I have got this working like this:
<script type="text/javascript">
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = 'http://www.google.com/jsapi';
headID.appendChild(newScript);
</script>
<script type="text/javascript">
google.load("language", "1");
</script>
It returned no errors.
Content scripts may access only the functions of itself or other content scripts. Since you add google api loader to the document's scripts, you can't call it from your content script. :)
If you need to load apis into the document's scripts, you can do it by specifying autoload parameter :
"https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22language%22%2C%22version%22%3A%221%22%7D%5D%7D"
http://code.google.com/apis/loader/autoloader-wizard.html

Categories

Resources