Problem with XmlHttpRequest (0x80040111 / nsIXMLHttpRequest.status) on several configurations

B

bollax

It would seem to me FF has a major bug in dealing with File downloads
or especially Audio files.

I've found not only does it cause the AJAX to error but linking to
audio also breaks the "Back Button" so to speak, not in the browser
itself but in the javascript method history.back(-1).

If you are on a page, click a link to another page with audio links on
it, click the audio link and then click the button provided to "GO
BACK", the browser tries to go back but just reloads the page you are
currently on. It's doesn't even reload the audio file, which
technically it should with the way the browser is behaving.

I'm having to go through my website and hardcode URLs on certain menu
option because I tried to use Internet standards and not break the
"back button", so issued history.back(-1) but because of the pathetic
way FF handles a URL to MP3's , being browser/user friendly is not
possible.

Why FF see's a hyperlink to an audio file as if the browser has gone to
another page is beyond me, because it hasn't. All I know is this is the
biggest reason i've ever seen to not use FF.

As i run a record music site and the way FF handles audiofiles, FF has
to be my biggest nightmare!

click an audio file in FF and bang, there goes the history.back(-1)
method, there goes your AJAX request, i'm sure there are more things it
trashes also, what a nightmare.

Anyone got any ideas as to a way to deal with this?
 
V

VK

It would seem to me FF has a major bug in dealing with File downloads
or especially Audio files.

I've found not only does it cause the AJAX to error but linking to
audio also breaks the "Back Button" so to speak, not in the browser
itself but in the javascript method history.back(-1).

<A href > - unless default action is cancelled - means *navigation* to
the resource indicated by href. Therefore FF behavior is completely
correct.
It would help to understand you interface:
<a href="someMusic.mp3" onclick="someFunction()">
- does it mean that you are loading mp3 file to the browser window
*and* executing someFunction() ? That doesn't have too much sense but
in any case FF is still totally right.

<span onclick="someFunction('someMusic.mp3')">Clip 001</span> is
universally correct (with MP3 player object on the page you handle over
your someFunction).
 
B

bollax

Thanks for the reply, sorry, I'm used to linking to an audio file with
href and have never had a problem in I.E. , this FF behaviour seems
alien to me.

Personally I don't like the way it is behaving but am more than happy
to try anything to make my site more cross browser compatible.

So I would appreciate your further assistance is that's ok.

I see you are using the span tag, does this mean I need to add somthing
like span:hover {CSS} , span:active{CSS}, span:link{CSS} etc to my CSS
file... so they behave like my anchor's do via the CSS.

Also what would "someFunction('someMusic.mp3')" actually do to initiate
the browser to play the audio file.

Are you saying I should have an audio player object embeded in the
page, and not use the, as I thought "universally accepted way" of
allowing the user to have their own, default audio player play the
music? - in my case I choose RealPlayer to play audio files, others use
WinAmp, some Windows Media Player.

Or is there an object that you can have that is a mechanism to pass the
audio file to the users "default" audio player.

Any help understanding the correct method and implementing it, is much
appreciated.
 
V

VK

Thanks for the reply, sorry, I'm used to linking to an audio file with
href and have never had a problem in I.E. , this FF behaviour seems
alien to me.

OK, let's call it "boring correct" or "inconveniently correct" :)
Indeed while navigating to .mp3 file it is clear that *this content*
will not be displayed in the browser window (unlike say an image file).
Personally I don't like the way it is behaving but am more than happy
to try anything to make my site more cross browser compatible.

So I would appreciate your further assistance is that's ok.

I see you are using the span tag, does this mean I need to add somthing
like span:hover {CSS} , span:active{CSS}, span:link{CSS} etc to my CSS
file... so they behave like my anchor's do via the CSS.

This one, or just override default link behavior by returning false
from click event:
<a href="foo.html" onclick="myFunction('music.mp3');return false">

I like the above lesser than a whole separate tag for psi-links but who
cares what do I like or not? :)
Also what would "someFunction('someMusic.mp3')" actually do to initiate
the browser to play the audio file.

It is really a whole separate question of playing / downloading media
files from a web-page. Seems simple like a moo-cow, but small details
give you real hell as soon as you try to support more than one browser.

Yes, I would use <object><embed> combo to activate default player for
the current system. But <object><embed> combo by itself is a whole
science to layout it in a "no-crash" way.

Really if you already have a working solution for IE I would try adjust
it somehow for Firefox and hell on standards.
How about creating a hidden iframe named say "hellOnThem" and dump MP3
files into it?
<a href="music.mp3" target="hellOnThem" onclick="myFunction()">
This dirty trick helped me once with Netscape, but a while ago.
 
B

bollax

Thanks for the advice.

would <a href="music.mp3" onclick="myAJAX('vars');return false"> " do
the job? open the mp3 but not add to history due to the return false?

If i used a hidden iframe, would that still give problems with the
busted history.back(-1); issue?

oh and what's a psi-link ?
 
V

VK

Thanks for the advice.

would <a href="music.mp3" onclick="myAJAX('vars');return false"> " do
the job? open the mp3 but not add to history due to the return false?

No - because "return false" prevents the link from the default action
(navigation). It is merely equivalent of <span
onclick="myAJAX('vars')">
If i used a hidden iframe, would that still give problems with the
busted history.back(-1); issue?

I don't know about Firefox - but I know the way to know: just try it
;-)
oh and what's a psi-link ?

My personal donation to the computer lingo :)

"HTML link used to trig JavaScript execution while staying on the same
page"

Feel free to use the above description, "pseudo-link", > "psi-link" or
coin your own term :)
 
B

bollax

I suppose PSI-Links are taboo ?

I guess I caould always have <a href="#'" onlclick="doAJAX"> and the
ajax return sub does document.location.href to the mp3 file.

then it wouldn't matter as the ajax will have finished processign and
returned. as long as document.location.href to an audio file doesn't
make the page go blank/white.

I'll play with a few methods and see what works best.

Thanks for all the help.
 
V

VK

I suppose PSI-Links are taboo ?

PSI-Links is not really a taboo, but they have some implications on
different browsers. In your case it is really tricky because you want a
link to work as a real link (load mp3 file) and as psi-link (execute
XMLHttpRequest request). It is not a taboo by itself but it seems that
Firefox is not happy with that - so may be some other browser we don't
know yet.
I guess I caould always have <a href="#'" onlclick="doAJAX"> and the
ajax return sub does document.location.href to the mp3 file.

That would be really risky because document.location.href means that
the current script context is free to be disposed, and you don't want
it.
Also you may do not want to ugly up your solution with frames.

So I would stay with iframe if it works. I just checked it on Firefox
1.5 and it seems doesn't affect history.length. But I did not check it
through:

<iframe name="foo"></iframe>
<a href="03.mp3" target="foo" onclick="alert(history.length)">Link</a>
<a href="02.mp3" target="foo" onclick="alert(history.length)">Link</a>
 
J

Jambalaya

I suppose PSI-Links are taboo ?

I guess I caould always have <a href="#'" onlclick="doAJAX"> and the
ajax return sub does document.location.href to the mp3 file.

then it wouldn't matter as the ajax will have finished processign and
returned. as long as document.location.href to an audio file doesn't
make the page go blank/white.

I'll play with a few methods and see what works best.

People have been doing this for years without AJAX by using a flash
movie in the page. Javascript interaction with flash is excellent and
flash is almost universally available.
<url:http://www.google.com/search?hl=en&q=flash+mp3+player+javascript>
 
A

Arnaud Diederen

VK said:
PSI-Links is not really a taboo, but they have some implications on
different browsers. In your case it is really tricky because you want a
link to work as a real link (load mp3 file) and as psi-link (execute
XMLHttpRequest request). It is not a taboo by itself but it seems that
Firefox is not happy with that - so may be some other browser we don't
know yet.


That would be really risky because document.location.href means that
the current script context is free to be disposed, and you don't want
it.
Also you may do not want to ugly up your solution with frames.

So I would stay with iframe if it works. I just checked it on Firefox
1.5 and it seems doesn't affect history.length. But I did not check it
through:

Personally, and I have no idea whether it is good practice, I use a
timeout function.
For example, if I'm using an XMLHttpRequest, in the
onreadystatechange() handler, when it comes to setting the
document.location.href, I'd wrap it in a timeout callback, rather than
do it directly:

------------- directly -----------
req.onreadystatechange = function {

if (req.readyState == 4) {

if (req.status == 200) {

document.location.href = ...
}
}
}
----------------------------------


------------- timeout -----------
req.onreadystatechange = function {

if (req.readyState == 4) {

if (req.status == 200) {

setTimeout (function () {

document.location.href = ...;
}, 100); // in 100 ms.
}
}
}
----------------------------------

That's it.
Has anyone any comment on whether this is good or bad?

Best regards,
Arnaud
 
T

Thomas 'PointedEars' Lahn

Arnaud said:
Personally, and I have no idea whether it is good practice, I use a
timeout function.
For example, if I'm using an XMLHttpRequest, in the
onreadystatechange() handler, when it comes to setting the
document.location.href, I'd wrap it in a timeout callback, rather than
do it directly:

------------- directly -----------
req.onreadystatechange = function {

if (req.readyState == 4) {

if (req.status == 200) {

document.location.href = ...
}
}
}
----------------------------------


------------- timeout -----------
req.onreadystatechange = function {

if (req.readyState == 4) {

if (req.status == 200) {

setTimeout (function () {

document.location.href = ...;
}, 100); // in 100 ms.
}
}
}

Considering that setTimeout() is unnecessary because the request is
asynchronous already; that using function object references for its
first argument is error-prone because not backwards compatible; that
document.location is deprecated ever since in favor of window.location;
that XMLHttpRequest is a host object that is not cross-browser and not
backwards compatible; that you do not feature-test anything before,
while a simple hyperlink, which in contrast does not depend on support
for client-side scripting, will do exactly the same _better_: it is BAD
-- Broken As Designed.


PointedEars
 
V

VK

Thomas said:
Considering that setTimeout() is unnecessary because the request is
asynchronous already; that using function object references for its
first argument is error-prone because not backwards compatible; that
document.location is deprecated ever since in favor of window.location;
that XMLHttpRequest is a host object that is not cross-browser and not
backwards compatible; that you do not feature-test anything before,
while a simple hyperlink, which in contrast does not depend on support
for client-side scripting, will do exactly the same _better_: it is BAD
-- Broken As Designed.

Wow!

Thomas 'PointedEars' Lahn just cancelled AJAX. Poor people of the world.
 
A

Arnaud Diederen

Thomas 'PointedEars' Lahn said:
Arnaud said:
Personally, and I have no idea whether it is good practice, I use a
timeout function.
For example, if I'm using an XMLHttpRequest, in the
onreadystatechange() handler, when it comes to setting the
document.location.href, I'd wrap it in a timeout callback, rather than
do it directly:
[...]
That's it.
Has anyone any comment on whether this is good or bad?

Considering that setTimeout() is unnecessary because the request is
asynchronous already;

I don't see your point. The request is asynchronous; that I know
already (though I can force it to be synchronous, and you couldn't
tell by looking at this code), but that's irrelevant, since the code I
posted was callback code.
that using function object references for its
first argument is error-prone because not backwards compatible;

I didn't know that
that
document.location is deprecated ever since in favor of
window.location;

Indeed, I use window.location, but that was just for the example,
sorry for the mistake.
that XMLHttpRequest is a host object that is not cross-browser and not
backwards compatible;

You seem to pay a lot of attention to looking backwards. What about
using the actual features when they are available? Why couldn't I?
that you do not feature-test anything before,

Indeed, I didn't, that's just an example
while a simple hyperlink, which in contrast does not depend on support
for client-side scripting, will do exactly the same _better_: it is BAD
-- Broken As Designed.

Ok: say you're in "myFrame", you issue an XMLHttpRequest (or
whatever substitute, depending on the browser) *from within* that
frame and, when you get the response, you find out(1) that you should
change "myFrame"'s location (reload it or whatever).

How do you do that within FF without triggering the exception the OP
just described?
My solution is (sorry, I realize I was not clear at first): getting
another frame (say "myRootFrame"), and setting a timeout function in
"myRootFrame" that will change "myFrame"'s location.
What is your solution? I don't understand it.

(1) I specified "you find out" because you might not need to refresh it.

Arnaud
 
T

Thomas 'PointedEars' Lahn

VK said:
Thomas said:
Arnaud said:
Personally, and I have no idea whether it is good practice, I use a
timeout function. [...]
[...]
------------- timeout -----------
req.onreadystatechange = function {

if (req.readyState == 4) {

if (req.status == 200) {

setTimeout (function () {

document.location.href = ...;
}, 100); // in 100 ms.
}
}
}

Considering that setTimeout() is unnecessary because the request is
asynchronous already; that using function object references for its
first argument is error-prone because not backwards compatible; that
document.location is deprecated ever since in favor of window.location;
that XMLHttpRequest is a host object that is not cross-browser and not
backwards compatible; that you do not feature-test anything before,
while a simple hyperlink, which in contrast does not depend on support
for client-side scripting, will do exactly the same _better_: it is BAD
-- Broken As Designed.

Wow!

Thomas 'PointedEars' Lahn just cancelled AJAX.

I did not such thing.
Poor people of the world.

Poor VK who still does not understand.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Arnaud said:
Thomas 'PointedEars' Lahn said:
Arnaud said:
Personally, and I have no idea whether it is good practice, I use a
timeout function.
For example, if I'm using an XMLHttpRequest, in the
onreadystatechange() handler, when it comes to setting the
document.location.href, I'd wrap it in a timeout callback, rather than
do it directly:
[...]
That's it.
Has anyone any comment on whether this is good or bad?
Considering that setTimeout() is unnecessary because the request is
asynchronous already;

I don't see your point. The request is asynchronous; that I know
already (though I can force it to be synchronous, and you couldn't
tell by looking at this code), but that's irrelevant, since the code I
posted was callback code.

What are you trying to achieve with setTimeout(), that is, asynchronous (but
not threaded) evaluation/call, if the request is asynchronous already? The
event listener will not be called before a response is received, and the
`location' object will not be touched if the response status is different
than 200 (OK). What you achieve with setTimeout() here is merely delaying
evaluation/call for another 100 milliseconds. I fail to see any point in
that.
I didn't know that

Solution: Either use a string value, or do a feature test and choose a
calling method, or change your described requirements instead. BTW: your
function expressions are missing an argument list "`(...)'" and are
therefore none, but I assume that is because of the example, too.
You seem to pay a lot of attention to looking backwards. What about
using the actual features when they are available? Why couldn't I?

Of course you could, and you should iff they are required. However, a
previous feature test is required on runtime or you will write a script
that will _break_, not only one that does not work.
Ok: say you're in "myFrame", you issue an XMLHttpRequest (or
whatever substitute, depending on the browser) *from within* that
frame and, when you get the response, you find out(1) that you should
change "myFrame"'s location (reload it or whatever).

How do you do that within FF without triggering the exception the OP
just described?
My solution is (sorry, I realize I was not clear at first): getting
another frame (say "myRootFrame"), and setting a timeout function in
"myRootFrame" that will change "myFrame"'s location.
What is your solution? I don't understand it.

Unfortunately, without further information from the OP ISTM that it is not
possible to devise a real solution to the problem. He thinks the cause of
this non-reproducible problem is req.send(null), but I still doubt that.

As for your problem, which does not strike me to have much to do with that
of the OP, you just leave the setTimeout() out, use `window.location'
instead of `document.location', and do the feature tests on runtime before.
Everything else is fine with your solution to _your_ problem to me.
However, your problem does not strike me being one in the first place
because

<a href="...">...</a>

will do exactly the same as your example does and it does not depend on
support for client-side scripting or any host object at all. Even if
we are talking about conditional navigation, this can be done better
server-side.
(1) I specified "you find out" because you might not need to refresh it.

Pardon? What is to be refreshed? Are you trying to say you want to check
if a resource is new and refresh its display only if that applies? If yes,
caches and cache control have been invented for that already.

Please elaborate.


PointedEars
 
A

Arnaud Diederen

Thomas 'PointedEars' Lahn said:
Arnaud said:
Thomas 'PointedEars' Lahn said:
Arnaud Diederen (aundro wrote:
Personally, and I have no idea whether it is good practice, I use a
timeout function.
For example, if I'm using an XMLHttpRequest, in the
onreadystatechange() handler, when it comes to setting the
document.location.href, I'd wrap it in a timeout callback, rather than
do it directly:
[...]
That's it.
Has anyone any comment on whether this is good or bad?
Considering that setTimeout() is unnecessary because the request is
asynchronous already;

I don't see your point. The request is asynchronous; that I know
already (though I can force it to be synchronous, and you couldn't
tell by looking at this code), but that's irrelevant, since the code I
posted was callback code.

What are you trying to achieve with setTimeout(), that is, asynchronous (but
not threaded) evaluation/call, if the request is asynchronous already? The
event listener will not be called before a response is received, and the
`location' object will not be touched if the response status is different
than 200 (OK). What you achieve with setTimeout() here is merely delaying
evaluation/call for another 100 milliseconds. I fail to see any point in
that.

Ok, I'll say it again then. The scenario is:

Imagine an application with many frames:

+--------------+
+--------------+
|myRoot |
| |
| +-------+|
| |mySub ||
+-----+-------++


- Now, Joe user clicks on a button that is inside "mySub". That click
will use an asynchronous call to the server to perform some
action (using an XMLHttpRequest).

- The server replies that the frame "mySub" needs to be
refreshed/changed. It *might* be unnecessary to reload "mySub", but
for example, let's say "mySub" needs to be refreshed.

- The request was issued from "mySub", and the callback function for
the onreadystatechange is a function that sits in the scope of
"mySub". From that function, if you do a
`window.location.href = "http://..."', FireFox will complain, throwing
this weird error that is the _title_ of this thread.

==> So: you cannot set the href of the location (or, in other words:
request that a new document is loaded) of the window from the
onreadystatechange handler of an XMLHttpRequest that was performed
from that window.

My solution to this is: I setTimeout() in "myRoot"'s scope, *delaying
the loading of the new document after I have had the time to leave the
onreadystatechange handler of the request*

Solution: Either use a string value, or do a feature test and choose a
calling method, or change your described requirements instead. BTW: your
function expressions are missing an argument list "`(...)'" and are
therefore none, but I assume that is because of the example, too.

Yes, Thomas, yes..
Of course you could, and you should iff they are required. However, a
previous feature test is required on runtime or you will write a script
that will _break_, not only one that does not work.

I _know_ that, thanks
Unfortunately, without further information from the OP ISTM that it is not
possible to devise a real solution to the problem. He thinks the cause of
this non-reproducible problem is req.send(null), but I still doubt that.

Me too, as explained before.
As for your problem, which does not strike me to have much to do with that
of the OP, you just leave the setTimeout() out, use `window.location'
instead of `document.location', and do the feature tests on runtime before.
Everything else is fine with your solution to _your_ problem to me.
However, your problem does not strike me being one in the first place
because

<a href="...">...</a>

Please, understand and consider the scenario above.
will do exactly the same as your example does and it does not depend on
support for client-side scripting or any host object at all. Even if
we are talking about conditional navigation, this can be done better
server-side.


Pardon? What is to be refreshed? Are you trying to say you want to check
if a resource is new and refresh its display only if that applies? If yes,
caches and cache control have been invented for that already.

This is not a matter of bandwidth, but a matter of "losing some state"
in which the application was.
You see, I'm developping a geographic tool (map navigation, usage of
resource directories to find map features),
which is very dynamic, and requires quite a lot of JavaScript.
I could same the current state of a given window, reload this window
(taking advantage of caching), and then restore the previous state,
but this is not appriopriate in all cases.

Arnaud
 
B

bollax

Well my solution was the non-standards easy option.

hidden iframe 1px by 1px and the href to the mp3 targets the iframe.

which technically makes it no longer a PSI-Link ;-)

the AJAX runs fine and returns as expected.

and even the browser back button doesn't break.

I still concider it a bug in FF (the way it handles audio file links is
undesireable).

being technically correct isn't always the desired result!

but of course if FF has been made to handle these types of links in
this manner then FF is doing what it's been told, bug by design!

thanks to everyone who has helped and given their advice, now I have a
working page which is cross-browser compatible.

kind regards,

Craig.
 
D

daniel.maceira

Did you find a solution for the error 0x80040111
(NS_ERROR_NOT_AVAILABLE) ?!
I´m having the same problem...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top