How to XHR local files?

后端 未结 2 1956
清歌不尽
清歌不尽 2021-01-16 07:01

This fails by giving result of 0 instead of 200. Im sure this has to do with xmlhttprequests being not allowed to access local drive but that should only apply to web scope,

相关标签:
2条回答
  • 2021-01-16 07:25

    XHR for local files will result in status 0. That is normal and doesn't mean there was an error.
    XMLHttpRequest status refers to actual HTTP server response which is not the case in accessing local files, therefore a 0 is passed as status.

    From: How to convert an overlay extension to restartless

    Note: When using XMLHttpRequest to access a file:// URL the request.status is not properly set to 200 to indicate success. In such cases, request.readyState == 4, request.status == 0 and request.response will evaluate to true.

    Update:

    Personally I would use the API and not bother with status

    Example from: Connecting to Remote Content

    let url = "http://www.example.com/";
    let request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                  .createInstance(Components.interfaces.nsIXMLHttpRequest);
    request.onload = function(aEvent) {
      // code to do on success
      //window.alert("Response Text: " + aEvent.target.responseText);
    };
    request.onerror = function(aEvent) {
      // there was a problem, handle error
      //window.alert("Error Status: " + aEvent.target.status);
    };
    request.open("GET", url, true);
    request.send(null);
    

    I use a modified version of above in my own add-ons.

    0 讨论(0)
  • 2021-01-16 07:38

    Thanks to @erosman an XHR to local file always returns status 0 but there is data in it. So I modified my xhr function to check on load if scheme of url is file uri and if its file uri than it accepts request.

    var {Cu: utils, Cc: classes, Ci: instances } = Components;
    Cu.import('resource://gre/modules/Services.jsm');
    Cu.import('resource://gre/modules/osfile.jsm');
    
    var pathh = OS.Path.toFileURI(OS.Path.join(OS.Constants.Path.desktopDir, 'mdn.png'));
    xhr(pathh, data => {
        Services.prompt.alert(null, 'XHR Success', data);
    });
    
    
    
    /****my xhr func****/
    function xhr(url, cb) {
        let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
    
        let handler = ev => {
            evf(m => xhr.removeEventListener(m, handler, !1));
            Services.ww.activeWindow.alert('ev.type=' + ev.type);
            switch (ev.type) {
                case 'load':
                    if (xhr.status == 200) {
                        cb(xhr.response);
                        break;
                    } else if (xhr.status == 0) {
                        var uritest = Services.io.newURI(url, null, null);
                        if (uritest.schemeIs("file")) {
                            //http://stackoverflow.com/a/25585661/1828637
                            //xhr'ing file uri always returns status 0 so this is not a real error
                            //so lets call cb and break
                            cb(xhr.response);
                            break;
                        } else {
                            //dont break so it goes into default error report
                            console.log('uri scheme is not file so it was real error, scheme was: ', uritest.scheme);
                        }
                    }
                default:
                    Services.prompt.alert(null, 'XHR Error', 'Error Fetching Package: ' + xhr.statusText + ' [' + ev.type + ':' + xhr.status + ']');
                    break;
            }
        };
    
        let evf = f => ['load', 'error', 'abort'].forEach(f);
        evf(m => xhr.addEventListener(m, handler, false));
    
        xhr.mozBackgroundRequest = true;
        xhr.open('GET', url, true);
        xhr.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS | Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_PERSISTENT_CACHING;
        //xhr.responseType = "arraybuffer"; //dont set it, so it returns string, you dont want arraybuffer. you only want this if your url is to a zip file or some file you want to download and make a nsIArrayBufferInputStream out of it or something
        xhr.send(null);
    }
    
    0 讨论(0)
提交回复
热议问题