Ticket #4545 (closed bug: duplicate)
Local scripts loaded from $.getScript fail if an external script is also loaded
| Reported by: | drawrof | Owned by: | |
|---|---|---|---|
| Priority: | high | Milestone: | 1.5 |
| Component: | core | Version: | 1.4.2 |
| Keywords: | Cc: | ||
| Blocking: | Blocked by: |
Description
It appears that $.getScript fails to load and/or fire callbacks when an external script is also loaded. If I load a local script, say test.js, the callback fires fine. However, if I also load, for example, jQuery UI from the google ajax libraries externally, the local file's callback no longer fires. Firebug also reports that any variables defined in the local file are undefined.
This happened in FF3, but it worked fine in Safari 3.
Take a look at the attached test case.
Attachments
Change History
comment:1 Changed 3 years ago by jesse
The problem lies in running $.globalEval while loading a remote script. Both techniques rely on adding script elements to the page. $.globalEval uses a script element to evaluate the local JavaScript that was loaded via Ajax, and the remote script must be loaded using a script element.
FF3 waits until the previously added remote script element loads before executing $.globalEval's script element. This delay is what causes variables in the script to be undefined in the $.getScript callback.
comment:2 Changed 3 years ago by dmethvin
Just a thought, maybe the position in the document makes a difference? Right now, $.getScript and $.globalEval insert new script tags at the top of the head, so later scripts end up above the earlier ones in the head. Also since the script could document.write something and replace the existing document that may affect the browser's behavior.
comment:3 Changed 3 years ago by dmethvin
Well I experimented with inserting the script tags in different places in the document, and also tried using the {{{defer}} attribute, but no change.
comment:4 Changed 3 years ago by rejetto
here i can easily reproduce the bug. i'm using firefox 3.6.10 on windows 7. i also tried to change the jquery version with 1.4.2
i just downloaded the 2 attached files, ran the html one, and what i got is only the 'JQUERY UI LOADED' alert. The other alert (LOCAL FILE LOADED) is never displayed, because at the time of the alert() the variable is not set, and so it's skipped. As a proof that is just skipped because of the var, you can change the var with a literal like 123, then get you the alert (after the 'JQUERY UI LOADED', that's fine, being it async).
Because of this bug i'm currently using a patched version of jquery, treating "local" files just as the remote files.
comment:5 Changed 3 years ago by snover
- Priority changed from major to high
- Status changed from new to open
- Version changed from 1.3.2 to 1.4.2
- Milestone changed from 1.4 to 1.5
What is the reason that remote script loads are treated differently and processed through an XHR + globalEval instead of just being appended?
comment:8 Changed 2 years ago by jaubourg
- Keywords ajaxrewrite removed
- Component changed from ajax to core
The reason for ajax always trying to use xhr for same domain requests is to ensure completion as much as possible and to avoid DOM pollution (both of them for when an error occurs).
The problem here lies into globalEval which makes the assumption an inserted inline script element will be executed right away while it's clearly an asynchronous process in Firefox.
Even if you make all script requests (cross-domain or not) use script tag injection, it won't fix the fact that if you call globalEval manually while script requests are active it won't execute in Firefox (and marking all script tags as async does not fix the issue).
IIRC, jQuery switched to this inline script tag injection technique to handle scoping properly (notably dirty var statements out of a closure) with no global namespace pollution.
There's been some globally scoped eval discussions (see http://www.davidflanagan.com/2010/12/global-eval-in.html and kangax's comments) so it may prove interesting to see which supported browsers does NOT support indirect eval calls as a mean to eval in the global scope.
Anyway, this is a core module issue so I'll redirect this there.
comment:9 Changed 2 years ago by jaubourg
- Status changed from open to closed
- Resolution set to duplicate
Incidently, this is a duplicate of #7862.
comment:10 Changed 2 years ago by jaubourg
Duplicate of #7862.
Please follow the bug reporting guidlines and use jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.


Test Case