View Full Version : Why Ajax can not get local file ? while prototypejs can ?
outersky
5 Aug 2007, 2:13 AM
If I open local file ( click .html file directly ) , Ext.Ajax can not load another file in the same directory.
but if I publish this folder as a website, Ajax runs ok.
I used prototype.js before, its Ajax does not have this problem.
so I can view my page correctly without a web server.
Is there any way to fix this problem ?
Thanks!
perthkit
5 Aug 2007, 9:13 AM
I am not sure what do u mean by local file.
If u meant examples like:
http://extjs.com/deploy/ext-1.1/examples/grid/paging.html
http://extjs.com/deploy/ext-1.1/examples/view/chooser.html
It is because we need the function from PHP (server-side script) to complete the tasks. Javascript is a client-side script. For security reason, many functions are not provided by Javascript. Also, I shorter the development time by using some of the functions from server-side script, instead of using pure JS.
Like Filesystem Functions (eg: http://au.php.net/manual/en/ref.filesystem.php). I am sure prototypejs cannot provide most of server-side script Filesystem Functions although I didn't really play around with prototypejs.
Your web page will be uploaded to web server anyway. I don't really see the problem.
hendricd
6 Aug 2007, 5:42 AM
perthkit (et al):
What you've encountered is the classic 'httpStatus == 0' returned by XMLHttpRequest implementations while accessing a local file system rather than a true HTTP server. Many Ajax implementations (Ext included at the moment) often consider a '0' httpstatus as an error/non-event.
You have two basic choices to resolve this.
1) Override the singleton Ext.lib.Ajax as shown below (as the Ext widgets are designed primarily for Http server access).
2) Only(or also) consider the requestcomplete callback when accessing a local file system (which is triggered regardless of the httpstatus).
All should also note: IE7's new XHR object ('out of the the box') does not permit access to local file systems, so in this case, the override below forcefully throws an error to fallback to the ActiveX implementation (which does support local file system access.)
Ext.apply( Ext.lib.Ajax ,
{createXhrObject:function(transactionId)
{
var obj,http;
try
{
// throw if IE7 -- since it's new XHR implementation
// doesn't work for local file systems
if(Ext.isIE7)throw("IE7");
http = new XMLHttpRequest();
obj = { conn:http, tId:transactionId };
}
catch(e)
{
for (var i = 0; i < this.activeX.length; ++i) {
try
{
http = new ActiveXObject(this.activeX[i]);
obj = { conn:http, tId:transactionId };
break;
}
catch(e) {
}
}
}
finally
{
return obj;
}
},
handleTransactionResponse:function(o, callback, isAbort)
{
if (!callback) {
this.releaseObject(o);
return;
}
var httpStatus, responseObject;
try
{
if (o.conn.status !== undefined) { /*&& o.conn.status != 0) {*/
httpStatus = o.conn.status;
}
else {
httpStatus = 13030;
}
}
catch(e) {
httpStatus = 13030;
}
if(httpStatus == 0) httpStatus = 200;
if (httpStatus >= 200 && httpStatus < 300) {
responseObject = this.createResponseObject(o, callback.argument);
if (callback.success) {
if (!callback.scope) {
callback.success(responseObject);
}
else {
callback.success.apply(callback.scope, [responseObject]);
}
}
}
else {
switch (httpStatus) {
case 12002:
case 12029:
case 12030:
case 12031:
case 12152:
case 13030:
responseObject = this.createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false));
if (callback.failure) {
if (!callback.scope) {
callback.failure(responseObject);
}
else {
callback.failure.apply(callback.scope, [responseObject]);
}
}
break;
default:
responseObject = this.createResponseObject(o, callback.argument);
if (callback.failure) {
if (!callback.scope) {
callback.failure(responseObject);
}
else {
callback.failure.apply(callback.scope, [responseObject]);
}
}
}
}
this.releaseObject(o);
responseObject = null;
}});
You'll have to decide which approach (or another) is best for you, however. I chose the overrides as defined above as I am developing an App used solely with local CD/DVD file systems AND heavy widget (Ext only) usage.
Enjoy this food-for-thought.
sjivan
6 Aug 2007, 5:48 AM
This seems like a nice addition to have in Ext. Are they any downsides to this? Its nice to be able to open local samples where they access data files like plants.xml and have the sample work.
Sanjiv
mystix
6 Aug 2007, 5:52 AM
wow hendricd, thanks for the nice override. =D>
guess i'll have to eat my words and retract all those "you need a webserver to run XHR" statements. :)
hendricd
6 Aug 2007, 6:00 AM
If Ext.core.team were to reconsider the status==0 issue (as mootools, Prototype, etc) already have, it would add a great deal of flexibility for all [IMHO].
The IE7/XHR problem should probably be addressed more formally in createXhrObject as a config option, so you can decide which IE7:XHR implementation serves you best.
mystix
6 Aug 2007, 10:26 AM
If Ext.core.team were to reconsider the status==0 issue (as mootools, Prototype, etc) already have, it would add a great deal of flexibility for all [IMHO].
The IE7/XHR problem should probably be addressed more formally in createXhrObject as a config option, so you can decide which IE7:XHR implementation serves you best.
hey hendricd, maybe you'd like to put this up in the general discussions forum for better mileage? ;)
hendricd
6 Aug 2007, 12:08 PM
Yeah, I'll move the key points over there...
hendricd
6 Aug 2007, 12:12 PM
Repost of Thread (http://extjs.com/forum/showthread.php?p=52156#post52156):
perthkit (et al):
What you've encountered is the classic 'httpStatus == 0' returned by XMLHttpRequest implementations while accessing a local file system rather than a true HTTP server. Many Ajax implementations (Ext included at the moment) often consider a '0' httpstatus as an error/non-event.
You have two basic choices to resolve this.
1) Override the singleton Ext.lib.Ajax as shown below (as the Ext widgets are designed primarily for Http server access).
2) Only(or also) consider the requestcomplete callback when accessing a local file system (which is triggered regardless of the httpstatus).
All should also note: IE7's new XHR object ('out of the the box') does not permit access to local file systems, so in this case, the override below forcefully throws an error to fallback to the ActiveX implementation (which does support local file system access.)
Ext.apply( Ext.lib.Ajax ,
{createXhrObject:function(transactionId)
{
var obj,http;
try
{
// throw if IE7 -- since it's new XHR implementation
// doesn't work for local file systems
if(Ext.isIE7)throw("IE7");
http = new XMLHttpRequest();
obj = { conn:http, tId:transactionId };
}
catch(e)
{
for (var i = 0; i < this.activeX.length; ++i) {
try
{
http = new ActiveXObject(this.activeX[i]);
obj = { conn:http, tId:transactionId };
break;
}
catch(e) {
}
}
}
finally
{
return obj;
}
},
handleTransactionResponse:function(o, callback, isAbort)
{
if (!callback) {
this.releaseObject(o);
return;
}
var httpStatus, responseObject;
try
{
if (o.conn.status !== undefined) { /*&& o.conn.status != 0) {*/
httpStatus = o.conn.status;
}
else {
httpStatus = 13030;
}
}
catch(e) {
httpStatus = 13030;
}
if(httpStatus == 0) httpStatus = 200;
if (httpStatus >= 200 && httpStatus < 300) {
responseObject = this.createResponseObject(o, callback.argument);
if (callback.success) {
if (!callback.scope) {
callback.success(responseObject);
}
else {
callback.success.apply(callback.scope, [responseObject]);
}
}
}
else {
switch (httpStatus) {
case 12002:
case 12029:
case 12030:
case 12031:
case 12152:
case 13030:
responseObject = this.createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false));
if (callback.failure) {
if (!callback.scope) {
callback.failure(responseObject);
}
else {
callback.failure.apply(callback.scope, [responseObject]);
}
}
break;
default:
responseObject = this.createResponseObject(o, callback.argument);
if (callback.failure) {
if (!callback.scope) {
callback.failure(responseObject);
}
else {
callback.failure.apply(callback.scope, [responseObject]);
}
}
}
}
this.releaseObject(o);
responseObject = null;
}});
You'll have to decide which approach (or another) is best for you, however. I chose the overrides as defined above as I am developing an App used solely with local CD/DVD file systems AND heavy widget (Ext only) usage.
Enjoy this food-for-thought.
tryanDLS
7 Aug 2007, 5:14 PM
EDIT: Merged Help thread with this one.
hendricd
8 Aug 2007, 7:57 AM
The latest and greatest version of this override is now Here (http://extjs.com/forum/showthread.php?p=52350#post52350)
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.