Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #8998
| Message-ID | <1810376.7NaK4W3vae@PointedEars.de> (permalink) |
|---|---|
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
| Organization | PointedEars Software (PES) |
| Date | 2011-12-08 23:12 +0100 |
| Subject | Re: How to Create an XHR (Ajax) Object |
| Newsgroups | comp.lang.javascript |
| References | <c8822aed-a1a2-4009-a65d-686b79090c3e@s26g2000yqd.googlegroups.com> <jbpf64$d8r$1@news.albasani.net> |
| Followup-To | comp.lang.javascript |
Followups directed to: comp.lang.javascript
Andreas Bergmaier wrote:
> David Mark schrieb:
>> How to Create an XHR (Ajax) Object
>>
>> var xhrCreated;
>>
>> // As always, shorthand feature detection for example--use
>> isHostMethod in this case
>>
>> // Degrades in IE 6- :)
>>
>> if (this.XMLHttpRequest)
>> // Use try-catch as this host object may explode on creation
>>
>> try {
>> var x = new XMLHttpRequest();
>> xhrCreated = true;
>> } catch(e) {
>> }
>> }
>>
>> if (xhrCreated) {
>> var createXhrObject = function() {
>> return new XMLHttpRequest();
>> };
>> }
>>
>> if (createXhrObject) {
>> // Put app that must create XHR objects here
>> }
>>
>> In my experience, such IE fallback scripts are usually aimed at 8 and
>> under, but this one is only needed for 6 and under, so do this:-
>>
>> if (!createXhrObject) {
>> // Create ActiveX rendition here
>> }
>
> What do you think about
>
> if (!window.XMLHttpRequest)
> window.XMLHttpRequest = function() {
> try {
> return new (window.XMLHttpRequest = function XMLHttpRequest() {
> ActiveXObject.call(this, "Microsoft.XMLHTTP");
> });
> } catch(e) {
> try {
> return new (window.XMLHttpRequest = function XMLHttpRequest()
> {
> ActiveXObject.call(this, "Msxml2.XMLHTTP");
> });
> } catch(e) {
> delete window.XMLHttpRequest;
> throw new Error("This browser doesn't support any AJAX");
> }
> }
> };
>
> And then just use new XMLHttpRequest() whereever you need it?
I think it is utter nonsense. I wonder, have you even tried it?
- You are testing a property of the object referred to by `window' when you
are interested in a property of the global object.
- You are attempting to augment the host object referred to by `window'.
- Calling a callable object as property of another object is _not_
equivalent to using it as a constructor.
- You are calling `call' on a host object, but it does not need to inherit
from Function.prototype or otherwise implement that method. Since
`ActiveXObject' implements the method, but does not allow it to be called
on that object ("Automation server cannot create object"), assuming that
no other host-object specific peculiarities are involved, the first
attempt to use `new window.XMLHttpRequest' will delete
`window.XMLHttpRequest' and throw an Error exception; if that exception
is handled, subsequent attempts will throw a built-in TypeError exception.
- The `call' call is pointless. Your constructor does _not_ *return* a
reference to another object (as a factory would), so it returns a
reference to an "empty" Object instance:
return new (window.XMLHttpRequest = function XMLHttpRequest() {
ActiveXObject.call(this, "Microsoft.XMLHTTP");
});
evaluates to
window.XMLHttpRequest = function XMLHttpRequest() {
ActiveXObject.call(this, "Microsoft.XMLHTTP");
};
return new window.XMLHttpRequest();
which, assuming for a moment `call' works here, can be broken down into
var previousXHR = window.XMLHttpRequest;
window.XMLHttpRequest = function XMLHttpRequest() {
ActiveXObject.call(previousXHR, "Microsoft.XMLHTTP");
};
return new window.XMLHttpRequest();
which evaluates to the equivalent of
return {};
As a result, attempts to call XHR methods on the newly created object will
throw a built-in TypeError exception, while attempts to set event
listeners or other non callable properties will probably work but will do
nothing useful.
In case you have problems seeing any of the above, replace the relevant
parts with dummy parts that work basically the same:
var w = {},
global = this;
function A ()
{
console.log("A: ", arguments);
/* Disable this to see what happened if call() would work */
if (this != global)
{
throw new Error("Automation server cannot create object");
}
}
A.prototype.open = function () {};
if (!w.X)
w.X = function () {
try
{
return new (w.X = function X () {
A.call(this, "Microsoft.XMLHTTP");
});
}
catch (e) {
try
{
return new (w.X = function X () {
A.call(this, "Msxml2.XMLHTTP");
});
}
catch (e)
{
delete w.X;
throw new Error("This browser doesn't support any AJAX");
}
}
};
/* Disable this to see what happened if exception was not handled */
try
{
new w.X();
}
catch (e)
{
}
var x = new w.X();
/* TypeError */
x.open();
- You are using a named function expression. Doing that, you are
effectively declaring a function with that name in the local execution
context, due to a JScript bug (which is the ECMAScript implementation of
about the only environment that this code would be relevant for). This is
even more foolish as you are not referring to the function name in the
function (recursion without arguments.callee).
- The `XMLHttpRequest' behavior in JScript/MSHTML varies from that in MSXML,
and might even vary more from it in the future (when XMLHttpRequest2 might
be implemented). So you need to encapsulate this. (ISTM David's original
approach already falls short of that distinction.)
So you *really* do *not* want to do this.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
David Mark's Daily Javascript Tips - Volume #3 - Tip #10 - How to Create an XHR (Ajax) Object David Mark <dmark.cinsoft@gmail.com> - 2011-12-07 15:36 -0800
Re: How to Create an XHR (Ajax) Object Andreas Bergmaier <andber93@web.de> - 2011-12-08 05:41 +0100
Re: How to Create an XHR (Ajax) Object David Mark <dmark.cinsoft@gmail.com> - 2011-12-08 11:23 -0800
Re: How to Create an XHR (Ajax) Object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-12-08 23:12 +0100
Re: How to Create an XHR (Ajax) Object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-12-08 23:45 +0100
Re: How to Create an XHR (Ajax) Object David Mark <dmark.cinsoft@gmail.com> - 2011-12-08 16:38 -0800
Re: How to Create an XHR (Ajax) Object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-12-09 11:50 +0100
Re: How to Create an XHR (Ajax) Object David Mark <dmark.cinsoft@gmail.com> - 2011-12-09 12:08 -0800
Re: How to Create an XHR (Ajax) Object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-12-10 20:56 +0100
csiph-web