haxe.Http - JavaScript requesting local file not possible?

502 views
Skip to first unread message

der Raab

unread,
Jun 4, 2013, 11:20:21 AM6/4/13
to haxe...@googlegroups.com
Hi! I struggle with the really basic stuff using Haxe 3.

Usually I use jQuery to load some XML files which works for local environments (no http:, but file:) too. Firefox or even Chrome with enabled local file access.

Now I try load some local XML within a local HTML page but this won't work at all:

package;

import haxe.Http;

class Application implements IApplication {

    public function new() {

        testFileAccess();
    }

    private function testFileAccess() {

        var url : String = "data/_setup.xml";

        var http : Http = new Http( "" );
            http.url = url;

        http.onData = onHTTPData;
        http.onError = onError;
        http.onStatus = onStatus;

        http.request(false);
    }

    private function onHTTPData( data : String ) {

        trace( "onHTTPData:" + data );
    }

    private function onError( msg : String ) {
        trace( "onError:" + msg );
    }

    private dynamic function onStatus( status : Int ) {
        trace( "onStatus:" + status );
    }
}


Well, it does work in an server environment but I need local requests too. Here's the local output:
onStatus:0
onError:Http Error #0

Shouldn't this be supported? Do I need to create a workaround? Shall I use NME and will nme.URLLoader do the trick?

Or did I miss the point? Hm.

Please help! :)


Tero Tolonen

unread,
Jun 4, 2013, 11:30:26 AM6/4/13
to haxe...@googlegroups.com

This is a Chrome security restriction, you might be able to go around it with --allow-file-access-from-files


AS3Boyan

unread,
Jun 4, 2013, 12:22:05 PM6/4/13
to haxe...@googlegroups.com
Why not just start a local webserver
nekotools server -d path_to_directory
And use like "var url : String = http://localhost:2000/data/_setup.xml"

der Raab

unread,
Jun 5, 2013, 6:04:38 AM6/5/13
to haxe...@googlegroups.com
@Tero Tolonen: No, this has nothing to do with the Chrome security restriction. I'm already running it with local file access. And I have the same problem with Firefox! It runs fine when using jQuery.ajax().

@AS3Boyan: The app shall definitely rund run offline. Think about a phone gap application with local file access...

Do I need to use jQuery. Damn it. ;)

mark prades

unread,
Jun 5, 2013, 10:11:32 AM6/5/13
to haxe...@googlegroups.com
 this has nothing to do with the Chrome security restriction.
 


then check the headers when using jquery and use the same headers with Haxe api. it's simple.
that's what you should have done at first place.

der Raab

unread,
Jun 5, 2013, 12:58:15 PM6/5/13
to haxe...@googlegroups.com
Hi mark prades, setting the headers doesn't do the trick.

jQuery uses basically this snipped to emulate a success for local files:
// If the request is local and we have data: assume a success
// (success with no data won't get notified, that's the best we
// can do given current implementations)
if ( !status && s.isLocal && !s.crossDomain ) {
status = responses.text ? 200 : 404;
}

Since browsers report status 0 while loading this would do the trick with the haxe implementation:

haxe.Http.prototype = {
    request: function(post) {
        var onreadystatechange = function() {
        ... switch(s) {
            default:

                if (s == 0 && r.responseText )
                {
                    me.onData(r.responseText);
                }
                else {
   me.onError("Http Error #" + r.status);
            }
}

Adding the local and crossdomain check would be great too.

Should I file a feature request or just implement a solution and commit?

Tero Tolonen

unread,
Jun 5, 2013, 1:10:54 PM6/5/13
to haxe...@googlegroups.com


@Tero Tolonen: No, this has nothing to do with the Chrome security restriction. I'm already running it with local file access. And I have the same problem with Firefox! It runs fine when using jQuery.ajax().

Ahh... sorry read your post quite quickly, well... I got the same error, but I solved by installing Node.js to serve the files from my computers.
I wrote the Node.js server using Haxe too and server the files generated by Haxe... :)

BUT, If you want to use the Http to get local files, at least you should somehow tell the system that you want to use file:/// -protocol, 
if you are unsure you could check:


And if you look from lines 161 it looks like it might work if you specify the File:/// -protocol.


 

Juraj Kirchheim

unread,
Jun 5, 2013, 1:43:43 PM6/5/13
to haxe...@googlegroups.com
On Wed, Jun 5, 2013 at 6:58 PM, der Raab <goo...@derraab.com> wrote:
Should I file a feature request or just implement a solution and commit?

If fix it, test it and make a pull request, I think that's a lot more helpful than filing an issue ;)

der Raab

unread,
Jun 6, 2013, 6:39:00 AM6/6/13
to haxe...@googlegroups.com
Well, I have a functioning port of the jQuery approach:

haxe.Http.prototype = {
...
 ,request: function(post) {
  var me = this;
  var r = new js.XMLHttpRequest();
  var onreadystatechange = function() {
   if(r.readyState != 4) return;
    var s = (function($this) {
    var $r;
    try {
     $r = r.status;
    } catch( e ) {
     $r = null;
    }

    // local protocol fix borrowed from jQuery:


    // If the request is local and we have data: assume a success
    // (success with no data won't get notified, that's the best we
    // can do given current implementations)
    if (!$r) {
        $r = (function($r) {
            try {
                var ajaxLocation = location.href;
            } catch( e ) {
                ajaxLocation = document.createElement( "a" );
                ajaxLocation.href = "";
                ajaxLocation = ajaxLocation.href;
            }
            var rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
                rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
                ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [],
                isLocal = rlocalProtocol.test( ajaxLocParts[ 1 ] );
            if (isLocal) {
                $r = r.responseText ? 200 : 404;
            }
            return $r;
        })($r);
    }

   return $r;
  }(this));

BUT - I'm not happy with the implementation since it would be a much better approach to evaluate the local environment only once. Maybe it would be better to store it in js.isLocal or somewhere else?

Vishwa Kolkar

unread,
Mar 26, 2015, 5:19:20 AM3/26/15
to haxe...@googlegroups.com
Hi,

I used the same thing but still I don't get the data from xml.
I started the local server and modified the server dir and then assigned the xml file url like you said.
Did I miss anything.

Thank you
Vishwa

der Raab

unread,
Mar 26, 2015, 5:54:57 AM3/26/15
to haxe...@googlegroups.com
It's absolutely necessary to use POST requests! Maybe that will fix it?
Reply all
Reply to author
Forward
0 new messages