Getting URL of executing JavaScript file (IE6-7 problem mostly) - javascript

Hey all, I've been trying to throw together a generic function that retrieves the absolute URL of an executing JavaScript file on a web page:
http://gist.github.com/433486
Basically you get to call something like this:
getScriptName(function(url) {
console.log(url);
// http://www.example.com/myExternalJsFile.js
});
inside an external JavaScript file on a page and can then do something with it (like find the <script> tag that loaded it for example).
It works great in almost all the browsers I've tested (Firefox, Chrome, Safari, Opera v10 at least, and IE 8).
It seems to fail, however, in IE 6 and 7. The callback function gets executed, but the retrieved name is the URL to the main HTML page, not the JavaScript file. Continuing with the example, getScriptName invokes the callback with the parameter: http://www.example.com/index.html
So all I'm really asking is if there's some other way of getting the URL of the current JavaScript file (which could be IE 6 and 7 specific hackery)? Thanks in advance!
EDIT: Also, this won't work in every case, so please don't recommend it:
var scripts = document.getElementsByTagName("script");
return scripts[scripts.length-1].src;
I'd like it to work in the case of dynamically created script tags (possibly not placed last in the page), aka lazy-loading.

A lot of this depends on what you have access to. If, as it appears, you are trying to do this entirely within the JS code, I do not believe that you are able to do it, for some of the reasons shown above. You could get 90% of the way maybe, but not be definitive.
If you are working in a dotnet environment ( which is the only one I know ), I would suggest the use of a module that would intercept all JS requests and add into them the request location, or something of that nature.
I think you need to address this from the server side, not the client side. I do not think you will have a definitive answer form the client side. I think you will also struggle to get an answer from the server side, but you might be more successfull.

Sorry, I suspect you might struggle with this. IE earlier than version 8 typically gives error messages from javascript errors of the form:
line: 342
char: 3
error: expected identifier, string or number
code: 0
url: http://example.com/path/to/resource
where the url is the window.location.href, rather than the URL of the external Javascript resource that contains the problem. I suggest that IE gives the unhelpful URL value since the script URL isn't available to IE at that point, and neither is it available to any Javascript you might write to try to display it.
I would love to be able to link to IE8 release notes which say this bug / feature has been fixed, hence the reason I created this as community wiki. My MSDN foo is pretty weak!

Related

IE 11 Will not load systemjs

I am working with SystemJS and I have a pseudo-bootstrapper file that I use to check to make sure certain conditions are met before the loading of the main scripts to execute the page load. Here is a snippet of that code.
var obj = document.createElement('script');
obj.src = 'jspm_packages/system.js';
document.body.appendChild(obj);
This code does NOT execute the script, yet it does load it with a 200 code as evidenced by the network tab within the IE dev tools. There should be a global object "System" created, but it does not exist. Looking through the DOM, the object is properly created and appended to the body.
Does anyone know if this is strictly an issue with IE and SystemJS? I have no idea what's going on. I'm pulling my hair out, as per usual with the demon that is IE. I should note that every other browser works as expected, providing the "System" global variable.
EDIT Further testing has assured that this is not an issue with appendChild, as other scripts using the same method, execute on load just fine.
Reading this article tells us that your script may not run in IE11. The line in particular which is of interest is:
"Script elements with external resources should no longer execute during appendChild."
This appears to be what's happening.
EDIT: An alternate approach could be taken.
It would be a good idea to do condition checks on the server side before sending the response if you want to change page loading at the system.js level. If that is not possible then I'd suggest doing a redirect after the condition checks instead of appendChild.
The answer is that IE versions < Edge do not support promises. I needed a polyfill for IE 11.

How do I get the path of the currently running script with Javascript?

We have an IE extension implemented as a Browser Helper Object (BHO). We have a utility function written in C++ that we add to the window object of the page so that other scripts in the page can use it to load local script files dynamically. In order to resolve relative paths to these local script files, however, we need to determine the path of the JavaScript file that calls our function:
myfunc() written in C++ and exposed to the page's JavaScript
file:///path/to/some/javascript.js
(additional stack frames)
From the top frame I want to get the information that the script calling myfunc() is located in file:///path/to/some/javascript.js.
I first expected that we could simply use the IActiveScriptDebug interface to get a stacktrace from our utility function. However, it appears to be impossible to get the IActiveScript interface from an IWebBrowser2 interface or associated document (see Full callstack for multiple frames JS on IE8).
The only thing I can think of is to register our own script debugger implementation and have myfunc() break into the debugger. However, I'm skeptical that this will work without prompting the user about whether they want to break into the debugger.
Before doing more thorough tests of this approach, I wanted to check whether anyone has definitive information about whether this is likely to work and/or can suggest an alternative approach that will enable a function written in C++ to get a stack trace from the scripting engine that invoked it.
Each script you load may have an id and each method of the script calling myfunc() may pass this id to myfunc(). This means that first you have to modify myfunct() and finally alter your scripts and calls.
This answer describes how I solved the actual issue I described in the original question. The question description isn't great since I was making assumptions about how to solve the problem that actually turned out to be unfounded. What I was really trying to do is determine the path of the currently running script. I've changed the title of the question to more accurately reflect this.
This is actually fairly easy to achieve since scripts are executed in an HTML document as they are loaded. So if I am currently executing some JavaScript that is loaded by a script tag, that script tag will always be the last script tag in the document (since the rest of the document hasn't loaded yet). To solve this problem, it is therefore enough just to get the URL of the src attribute of the last script tag and resolve any relative paths based on that.
Of course this doesn't work for script embedded directly in the HTML page, but that is bad practice anyway (IMO) so this doesn't seem like a very important limitation.

Send Javascript code to browser

Is there a way to send javascript commands to an open web running in a browser from the shell?
Let's say I have stackoverflow.com open with Chrome. Well, I'd like to send something like
alert('hi!');
from the shell, with something similar to the following:
$ send -t Chrome -w "stackoverflow.com" -c "alert('hi!')"
I was wondering this, because if I can write alert('hi!') on the javascript console of Chrome, I should be able to do the same with a call somewhere, right?
I've seen node.js but I think is not possible with that, please, let me know if I'm wrong.
I know the question could seem weird but I'm curious, thanks in advance :)
You can send JavaScript to Firefox through the jssh extension.
http://www.croczilla.com/bits_and_pieces/jssh/
This is what the Watir testing framework uses to automate Firefox.
I don't know of an equivalent for Chrome.
For IE seems like you can use good old VBScript: http://www.autohotkey.com/forum/topic7642.html
Worked for me just fine now with IE8. :)
Edit: to open this very question and alert JS value have this code as .vbs file and run it:
Dim oIE
Set oIE = CreateObject("InternetExplorer.Application")
oIE.Visible = 1
oIE.Navigate "http://stackoverflow.com/questions/4992552/send-javascript-code-to-browser/4992812"
Do While (oIE.Busy)
Wscript.Sleep 10
Loop
oIE.Navigate "javascript:alert(fkey);"
I think it is possible if you write and install some browser addon that would receive your signal, and do the job. Interesting question, ill be tracking it.
It is entirely up to the browser to provide this sort of functionality. In fact, the form of your problem isn't specific even to browsers:
I was wondering this, because if I can [provide some sort of input] to [a program] to make it [do something], I should be able to do the same with a call somewhere, right?
Some programs do indeed provide hooks for scripting, but if they don't, you're out of luck. There is certainly no guarantee that if you can do something via the GUI, then you can trigger the same action from a command line call.
Now the fact that most browsers provide some sort of plugin architecture, makes it much more likely that such a plugin exists that will listen for external input in this way, if this functionality is missing in the base product.
However, this is still going to be very specific to the particular model and even version of the browser you want to control - so if it's something you wanted to release into the wild, you'll need to be very specific with your requirements.
You can send arbitrary code to browser through the address bar! For example in AutoHotKey style,
send F6 //focus the address bar
send ctrl+v //given that your code is in clipboard
send enter
Now there is another question. Can we get the return value of the inject code? The answer is YES!
Assign your return value to document.title, and retrieve the window title from your application.
If the return value is too long (eg. a JSON format string), do the trick that
document.title='calculating...';
document.title=returnValue.subString(0,20);
sleep(10);
document.title=returnValue.subString(20,40);
sleep(10);
document.title=returnValue.subString(40,60);
...
document.title='finished';
Hope it works.

'Invalid Argument' Error in IE, in a line number that doesn't exist

I'm getting the following error in IE 6:
Line: 454
Char: 13
Error: Invalid Argument
Code: 0
URL: xxxxx/Iframe1.aspx
and I can't for the life of me find what's causing this.
This only happens in a situation where I have a main page that has several IFrames, and it only happens when I have one particular IFrame (the one pointed to by the URL in the error message), and that IFrame is invisible at the time of loading.
I've narrowed it up to there, but I still can't find anything more specific...
The IFrame in question doesn't have 454 lines in its HTML, nor do any of the JS files referred by it.
I tried attaching VS to iexplore.exe as a debugger, and it breaks when the error occurs, but then tells me "There is no source code available for the current location"...
Any suggestions on how I can go about chasing this one?
UPDATE: I found this problem through brute-force, basically, commenting everything out and uncommenting randomly...
But the question still stands: what is the rational way to find where the error is, when IE reports the wrong line number / file?
IE's Javascript engine is disgusting when it comes to debugging. You can try enabling script debugging in the Advanced Options, and then if you have Visual Studio installed it will jump to the place of error... if you're lucky. Other times you don't get anything, especially if the code was eval()'ed.
Another thing about these line numbers is that it doesn't reflect which file the error is happening in. I've had cases where the line number was actually correct, but it was in a linked .js file, not the main file.
Try using the Microsoft Script Debugger or DebugBar (http://www.debugbar.com) which may give you some better IE6 debugging tools. They always help me with IE6.
Also, does this happen in any newer versions of IE or just in IE6?
It's virtually impossible to debug this without a live example, but one thing that often causes an "Invalid Argument" error in Internet Explorer is trying to set an incorrect value for a style property.
So something like:
document.getElementById("foo").style.borderWidth = bar + "px";
when "bar" has the value null, or undefined, or is the string "grandma", will cause it, as "grandmapx" isn't a valid value for the borderWidth style property.
IE9 has a browser mode.
Open up Developer Tools, then select the version you want to emulate in the console, reload the page with errors, and the console will show you line numbers and the correct file where the error is.
I run into this problem a lot too, and I've also resorted to commenting everything out until I find the problem. One thing that I find to be useful is to add a try/catch block to every javascript method. Sometimes I add an alert to tell what method the error came from. Still tedious, but easier than trial and error commenting. And if you add them every time you write a new method it saves a lot of time in the event errors like those occur.
function TestMethod()
{
try
{
//whatever
}
catch (ex)
{
ShowError(ex.description);
//alert("TestMethod");
}
}
A note to other readers: I recently had this "Invalid argument." error reported in IE7-9 and eventually found that it was down to the way I was using setTimeout/setInterval.
This is wrong, in IE:
var Thing = {};
Thing.myFunc = function() { ... };
setTimeout(Thing.myFunc, 1000);
Instead, wrap the callback in an anonymous function like so:
var Thing = {};
Thing.myFunc = function() { ... };
setTimeout(function() { Thing.myFunc(); }, 1000);
and no more "invalid argument" errors.
Another possibility:
I do a lot of dev between two computers, at home and at work, so I often email myself or download pages from the server to work on. Recently I realised that Vista has a habit of unilaterally applying blocks to certain files when they are downloaded in certain ways, without notifying me that it is doing this.
The result is that, for example, an HTML page wants to access the .js file in its header, but it doesn't have permission to access local files. In this case, it doesn't matter what you write in the .js file, the browser will never even read it, and an irksome Line: 0 error will result.
So before you comb your code for an error, check your HTML page's properties, and see if it hasn't been blocked by the OS....
Like NickFitz pointed out, styling was an issue with my code.
document.getElementById('sums<%= event.id %>').style.border='1px solid #3b3b3b;'
I removed the border style and my IE issues were gone.

How can I execute javascript in Bash?

I try to get to a page straight from Bash at http://www.ocwconsortium.org/. The page appears when you write mathematics to the field at the top right corner. I tested
open http://www.ocwconsortium.org/#mathematics
but it leads to the main page. It is clearly some javascript thing. How can I get the results straight from Bash on the first page?
[Clarification]
Let's take an example. I have the following lines for a Math search engine in .bashrc:
alias mathundergradsearch='/Users/user/bin/mathundergraduate'
Things in a separate file:
#!/bin/sh
q=$1
w=$2
e=$3
r=$4
t=$5
open "http://www.google.com/cse?cx=007883453237583604479%3A1qd7hky6khe&ie=UTF-8&q=$q+$w+$e+$r+$t&hl=en"
Now, I want something similar to the example. The difference is that the other site contains javascript or something that does not allow me to see the parameters. How could I know where to put the search parameters as I cannot see the details?
open "http://www.ocwconsortium.org/index.php?q=mathematics&option=com_coursefinder&uss=1&l=&s=&Itemid=166&b.x=0&b.y=0&b=search"
You need quotes because the URL contains characters the shell considers to be special.
The Links web browser more or less runs from the commandline (like lynx) and supports basic javascript.
Even though the title of the post sounds general, your question is very specific. It's unclear to me what you're trying to achieve in the end. Clearly you can access sites that rely heavily on javascript (else you wouldn't be able to post your question here), so I'm sure that you can open the mentioned site in a normal browser.
If you just want to execute javascript from the commandline (as the title suggests), it's easy if you're running bash via cygwin. You just call cscript.exe and provide a .js scriptname of what you wish to execute.
I didn't get anything handled by JavaScript - it just took me to
http://www.ocwconsortium.org/index.php?q=mathematics&option=com_coursefinder&uss=1&l=&s=&Itemid=166&b.x=0&b.y=0&b=search
Replacing mathematics (right after q=) should work. You may be able to strip out some of that query string, but I tried a couple of things and and it didn't play nice.
Don't forget to encode your query for URLs.
You will need to parse the response, find the URL that is being opened via JavaScript and then open that URL.
Check this out: http://www.phantomjs.org/.
PhantomJS it's a CLI tool that runs a real, fully-fledged Browser without the Chrome.

Categories

Resources