Bug Tracker

Opened 11 years ago

Closed 9 years ago

Last modified 8 years ago

#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:
Blocked by: Blocking:

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 (2)

test.html (742 bytes) - added by drawrof 11 years ago.
Test Case
test.js (36 bytes) - added by drawrof 11 years ago.
Simple local JS file to load

Download all attachments as: .zip

Change History (12)

Changed 11 years ago by drawrof

Attachment: test.html added

Test Case

Changed 11 years ago by drawrof

Attachment: test.js added

Simple local JS file to load

comment:1 Changed 10 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 10 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 10 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 9 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 9 years ago by snover

Milestone: 1.41.5
Priority: majorhigh
Status: newopen
Version: 1.3.21.4.2

What is the reason that remote script loads are treated differently and processed through an XHR + globalEval instead of just being appended?

comment:6 Changed 9 years ago by Rick Waldron

This needs to be reverified with the new ajax module.

comment:7 Changed 9 years ago by Rick Waldron

Keywords: ajaxrewrite added; getScript external removed

comment:8 Changed 9 years ago by jaubourg

Component: ajaxcore
Keywords: ajaxrewrite removed

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 9 years ago by jaubourg

Resolution: duplicate
Status: openclosed

Incidently, this is a duplicate of #7862.

comment:10 Changed 9 years ago by jaubourg

Duplicate of #7862.

Note: See TracTickets for help on using tickets.