I have been trying to turn a bookmarklet into a small development environment that I can use for testing some javascript and sending commands easily on the fly and updating the code on my server quickly to see the result. This has half way worked using method's I have found in this site and google however it doesn't seem to work very well and sometimes randomly doesn't work. The end goal is to have a bookmarklet that I can click on from any page and it loads a javascript file I have saved on my server. I have created the following two bookmarklets to try and get this working:
Failed Method 1:
javascript:
var s = document.createElement('script');
s.type='text/javascript';
document.body.appendChild(s);
s.src='//smewth.com/test.js';
void(0);
Method 1 in one line bookmarklet form: javascript: var s = document.createElement('script'); s.type='text/javascript'; document.body.appendChild(s); s.src='//smewth.com/test.js'; void(0);
Failed Method 2:
javascript:(
function(){
var imported = document.createElement('script');
imported.type='text/javascript';
imported.src = 'https://smewth.com/test.js';
document.head.appendChild(imported);
})();
Method 2 in one line bookmarklet form: javascript:( function(){ var imported = document.createElement('script'); imported.type='text/javascript'; imported.src = 'https://smewth.com/test.js'; document.head.appendChild(imported); })();
I got method 1 by decomposing the kickass bookmarklet from (http://kickassapp.com/). The actual one I got from their site works fine on my browser no problems. I even did a direct substitution from the URL they were using to load with my URL. The second method I found while searching on this site and this actually worked for a small while and stopped working for some unknown reason (maybe different browsers). I tried appending this script object to the head and the body on each of them with no improved results.
I created the test.js script just for this post and it contains a simple alert box statement:
$$ [/]# cat test.js
alert("hi");
$$ [/]#
NOTE: When I do this with the code embedded within the the bookmarklet itself without appending it to a head/body object then it works fine such as this:
javascript:%20alert("hi");
I did notice that with both of these methods, the code is actually getting injected into the page however I am not seeing the code is ever executed when I click the bookmark. Does anyone know which method is the best or something similar to do this so I can have javascript load through a page which I update on a remote server (reliably)? Maybe I need to attach the to a different object?
Thank you for your help.
-Jeff
UPDATE: I am showing this works while this site is loaded but it doesn't work when your at a site like google.com. Not sure what the difference is or how to accomodate this, google.com has a head and a body object too. I am showing this works in some sites and in some it doesn't.
I figured this out. There were two things occurring which accounts for the intermittent symptom of this issue. The first issue was that the site which was hosting the code was on a self-signed certificate. I began to notice the issue was occurring only when trying to run this from within secure sites. Then in Chrome I saw a error show up in the console. It would be nice if Firefox gave me a error on the console or something as this was the root of the issue. The second thing I had to do was disable OCSP in Firefox as I used a free certificate for testing purposes.
I also had to use method 1 as described above. Firefox and Chrome both did not like the anonymous function call for some reason. From now on I will refer to Chrome to look for errors in the console as Firefox has proven itself not very useful for this.
Related
We have an unusual problem with javascript running on IE 11. I tried it on one of our servers running IE8 and the same problem occurs. However, it runs fine on Chrome and Mozilla.
Here's the code in question:
SetGuideFatningCookie(fid); //set a cookie according to user choice
var validFatningCombo = ValidFatningCheck(); //ask server if user choice is valid using XMLHttpRequest GET request
if(validFatningCombo)
window.location.href = GetGuideTilbehoerURL(); //if valid redirect user to next page
else
popAutoSizeFancy("#GLfancy"); //if not show a fancybox with error text
The user chooses one of 7 choices. Then they click a button that runs the above code. The code sets a cookie containing the user's choice and asks the server if the choice is valid. If valid - we redirect the user and if not, we open a fancybox that contains some error text and two buttons - "Try again"(closes box and they can try again) and "Send us a message"(redirects user to our "ask us a question" page).
The code runs fine the first time the user goes to this process.
However, if they have chosen an invalid choice, they close the fancybox and try to choose another choice and continue -> then the fancy box appears ALWAYS, regardless of what the user chooses.
If they choose a valid choice and continue, get redirected to next page, then come back to this page and choose an invalid choice and press continue -> then they can continue to the next page without fancybox ever coming up.
However, if IE's developer tools are opened, the code runs correct every single time.
I have found many threads describing this is a problem with console.log. I have removed every single reference to console.log from all our .js files. It could be one of the external libraries that we are using, like jquery, modernizr, fancybox and menucool's tooltip library.
Therefore I tried including a console fallback function for IE, like this thread suggests:
Why does JavaScript only work after opening developer tools in IE once?
I am currently trying with this one, and I have tried every single other fallback console replacement from the thred I link to.
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };
I tried including it:
Somewhere in our .js files
script element in head after loading all our .js files and all external libraries
script element in head before loading all our .js files and all external libraries
Inside $(document).ready(function() {}); , in a script element in head after loading all other js
So far, none of the fallback pieces of code I have tried in any of these 4 locations have solved the problem. It always behaves the same way in IE. I couldn't find another explanation than the "console" one for this problem so far, so if anyone got any insight on it, it would be greatly appreciated.
EDIT: I will include some more info:
The very act of opening Developer Tools removes the unwanted behaviour. No errors are ever shown in console.
I checked the server side to see if the server is getting the call from ValidFatningCheck(); It turns out that the call is made only the first time (or if Developer tools is open - every time) which is rather mysterious since the redirect/fancybox line comes after the server call and it doesn't fail to run, even if it runs wrong.
function ValidFatningCheck(){
var requestUrl = '/Tools.ashx?command=validscreen';
var req = new XMLHttpRequest();
req.open('GET', requestUrl, false);
req.send(null);
var res = "";
if (req.readyState==4)
res = req.responseText;
if(res == "true")
return true;
return false;
}
UPDATE : Problem solved by adding a timestamp to my XMLHttpRequest as multiple replies suggested. I didn't realize XMLHttpRequest uses AJAX so I overlooked it as a probable cause to the problem.
(I put in comments but will make this an answer now as it appears to have solved the problem) get requests are cached by IE but when the developer console is open it does not perform this cache.
three ways to fix:
add a timestamp to the request to trick the browser into thinking it is making a new request each time
var requestUrl = '/Tools.ashx?command=validscreen&time='+new Date().getTime();
set the response header to no-cache
make a POST request as these are not cached
(as pointed out by #juanmendes not ideal you are not editing a resource)
I'm using an affiliate program which in this case means once a customer press the "order" button, he/she will get directed to the sellers website. The seller then registers that the customer came from OUR button, which is done by using a tracker that he registrates. This tracker gets executed on the "Order" button click, using the following code:
<script type="text/javascript">
$(function() {
function injectFile(filePath) {
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = filePath;
document.getElementsByTagName('body')[0].appendChild(newScript);
}
$('#custom_form').on('success.form', function() {
injectFile('https://example.com/&ti=' + Math.round((new Date().getTime() * Math.random())) + '&charset=ISO-8859-1');
});
});
</script>
I removed the actual URL and most of the parameters. ti represents an order ID that is needed for the reg to work, but it doesn't have to be valid. The above math generates a random number and inserts it.
By tracking the HTTP headers, I can confirm that this works in both Firefox and IE, since it requests the URL properly. In Chrome however, no request is registered and the seller won't see the customer coming from my end.
Sometimes the Chrome console displays this: "Resource interpreted as Script but transferred with MIME type text/html." However, this is just a warning and since it defines it as a script anyway it shouldn't affect the execution? Weird thing here is I don't get this error each time.
I have tried just about everything and I can't see why Chrome wouldn't be compatible with such a basic functionality. Is there a possible workaround or an actual fix to my issue?
Thanks in advance,
Fredrik
This is a bad configuration of the Apache / Nginx configuration of the remote server.
The mime-type of the file is not "text/javascript".
But no effect on your code ;)
Try running your code in an incognito window or a fresh install of Chrome - some extensions block asynchronous script loading from advertising or tracking sites in a way that is hard to detect.
I am creating a small javascript simulation of a java-based (JSF) server. The bootstrap javascript file will download and parse a bunch of files using AJAX, and then generate a large HTML string. This HTML string is a full HTML document - it has a doctype, head, script includes, inline scripts, body, etc.
The reason I do not want to use the real JSF back-end is because I would like to be able to have a pure UI environment to test my code without any java/oracle server slowing me down.
I want to share my code (in a .zip file for example) with anyone and they should be able to open the page (with a small loading screen while the AJAX calls are made) in any browser without some server already installed on their machine.
The answer to that question led me to explore more - now I've run into a different error but I cannot seem to explain it.
Fiddle #1 : This one attempts to put the HTML into an iframe using the iframe's document.write. In this HTML there is a script that pushes a new history state history.pushState(null, null, hash)
Fiddle #2 : This one attempts to put the HTML into the iframe, but this time it just uses location.hash = hash
Both fiddles seem to work fine in Chrome and Safari and IE 9 - but Firefox gives the following error:
NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMHistory.pushState]
I don't understand this error - if you do this same code history.pushState(null,null,"#test") on any page in firefox using the javascript console in FireBug it works fine - but in this particular situation it doesn't work.
I also tried to perform document.open(); document.write(html); document.close() on the document in the current page (instead of creating an iframe), but the same problem happened - only this time if I put break points in firebug into javascript code inserted in the HTML fragment, the breakpoints don't work which would mean I could no longer debug anything in firefox. At least with the iframe approach, the breakpoints work.
Can anyone shed some light into this problem?
Here is another related question that I asked yesterday which lead to finding this error: Firefox Fail - After using document.write and update to location.hash causes page refresh
You can put this code
history.pushState(null,null,"#test")
before
document.open();
document.write(html);
document.close();
I have run into a similar issue trying to open an Ember app using history.pushState (Ember Router location: 'history' method of routing) inside an iframe. It appears the issue only occurs when doing a hard refresh (cmd + shift + r on Mac or ctrl + f5 on Windows) in Firefox. The issue only occurs for me in FireFox, works fine in Chrome and Safari with similar hard refresh.
The issue does not occur for me when navigating to the page for the first time or when normally refreshing the page (cmd + r Mac, f5 Windows). I have found many seemingly related on Bugzilla for Mozilla but many are close. This one seems to represent the same issue I am having and is still open as of current versions of Firefox (v37.0.1 at time of writing).
https://bugzilla.mozilla.org/show_bug.cgi?id=1003100
When I click "Print" using the jQuery Print Preview Plugin the following error pops up and Firebug:
Error: Permission denied to access property 'name'
if (window.frames[i].name == "print-frame") {
I am not sure exactly what it means or how to correct it.
There is a way around this that will solve this problem and work properly with all major browsers. This solution was found by Derick over on the Github page for jQuery Print Preview.
Here is the solution, around line 44 you will see the following code:
// The frame lives
for (var i=0; i < window.frames.length; i++) {
if (window.frames[i].name == "print-frame") {
var print_frame_ref = window.frames[i].document;
break;
}
}
Replace the above code with this:
print_frame_ref = print_frame[0].contentWindow.document;
issue solved.
Here is the error in Chrome, I expect this makes it clear?
Unsafe JavaScript attempt to access frame with URL http://s7.addthis.com/static/r07/sh090.html#iit=1341762779832&tmr=load%3D1341762779182%26core%3D1341762779520%26main%3D1341762779826%26ifr%3D1341762779833&cb=0&cdn=0&chr=UTF-8&kw=&ab=-&dh=www.ubhape2.com&dr=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F11384440%2Ferror-permission-denied-jquery-print-preview&du=http%3A%2F%2Fwww.ubhape2.com%2Ftest-print.html&dt=TEST%20Page&md=0&cap=tc%3D0%26ab%3D0&inst=1&irt=0&jsl=33&lng=en-US&ogt=&pc=men&pub=ra-4dfb00d56c76d2a5&ssl=0&sid=4ff9acdb1a41cc60&srd=0&srf=0.02&srp=0.2&srl=1&srx=1&ver=300&xck=0&xtr=0&og=&rev=114791&ct=1&xld=1&xd=1 from frame with URL http://www.ubhape2.com/test-print.html. Domains, protocols and ports must match.
Your page is located on ww.ubhape2.com and you are accessing a frame on s7.addthis.com
To fix this problem, change this line
<script type="text/javascript" src="https://s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4dfb00d56c76d2a5"></script>
To point to the copied script on your site.
You will also have to edit that script to only access your own site.
This is an example of XSS or cross site scripting.
My question then turns into can I edit the jQuery Print Preview Script
to prevent the conflict from happening?
No.
The point of the error is that the javascript is running in the context of another party, and you can't "inject" your code into it.
This is enforced by the browser.
If it was not enforced then every user on the internet would have had their machines compromised.
Read up on a google search of XSS to find out more
However,
If you host the javascript (and thus the iframe) on your server than the issue goes away. It is your code (and your iframe) to do with as you wish.
I did not think it was possible but I hate IE6 twice as much now then this morning.
Please don't bug me about the why but I'll try to explain what we're trying to achieve.
We have 2 apps running, let's say APP1 & APP2, both of them are on the same domain. APP1 is including a JavaScript file that is hosted on APP2. This JS file will:
Create an IFrame (using document.createElement)
Set the source of the IFrame to the root of APP2 (where some HTML is generated);
Add a div to the body of APP1
Read the contents of the IFrame (so the generated HTML of APP2)
set this contents as the innerHTML of the div (3)
So in the end in APP1 we have a header where the contents is generated by APP2 without there being an IFrame on the screen.
The problem lies in step 4; this is working fine for all browsers except for IE6 (could this be the most used sentence in web development?).
I get a JS-error when trying to access contentWindow.document of the iframe: 'Access is denied'. I'm no expert but as I understand this error you would get if both apps were not on the same domain but they are (dev.echnet/APP1 & dev.echnet/APP2).
This is the code I use for above steps (took out stuff that is not executed if not IE6):
(1), (2) & (3):
var elIf;
$().ready(function()
{
elIf = document.createElement('<iframe name="uhframename">');
elIf.setAttribute('id','idUhFrame');
document.body.appendChild(elIf);
var uhDiv = document.createElement('div');
document.body.appendChild(uhDiv);
elIf.src='dev.echnet/APP1?nocache='+Math.random();
getText();
}
(4)
function getText() {
var sContent = "";
if (elIf.contentWindow.document.body) { // access denied on elIf.contentWindow.document
...
}
}
I've googled a lot and tried many possibilities I found (also on SO) but none of them seem to solve this issue.
I also tried setting the domain explicitly on the IFrame by settings its source to this:
"javascript:(function(){document.open();document.domain=\'dev.echnet\';document.close();})()"
but I'm not exactly sure if this has any effect since I'm setting the source to something else a few steps further. Anyway, since it's the same domain it should not matter?
Hoping for some help or someone to shoot down all IE6 users (a feasible task nowadays) so I can skip this task :-).
After some working with it for another question on here, I've come up with this solution.
Seems .document isn't always necessary.
http://jsfiddle.net/sTkVR/4/
I'm using chrome, and it was not working with .document but works like a charm with out it