2014-08-30 24 views
0

這個失敗的結果是0而不是200.我確定這與xmlhttprequests不允許訪問本地驅動器有關,但是它只應用於web範圍,而不是xpcom範圍的權利?如何XHR本地文件?

var pathh = OS.Path.toFileURI(OS.Path.join(OS.Constants.Path.desktopDir, 'test.png')); 
xhr(pathh, data => { 
    Services.prompt.alert(null, 'XHR Success', data); 
}); 

下面

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, 'test.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)); 
     switch (ev.type) { 
      case 'load': 
       if (xhr.status == 200) { 
        cb(xhr.response); 
        break; 
       } 
      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); 
} 

回答

2

XHR本地文件的完整代碼將導致status 0.這是正常的,並不意味着出現了錯誤。
XMLHttpRequeststatus指的是實際的HTTP服務器響應,在訪問本地文件時並非如此,因此0作爲status傳遞。

來源:How to convert an overlay extension to restartless

注意:在使用XMLHttpRequest來訪問file://網址的 request.status未正確設置爲200,表示成功。在這樣的 的情況下,request.readyState == 4,request.status == 0和 request.response將評估爲true。

更新:

個人而言,我會使用API​​,而不是從status

例打擾: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); 

我在我自己使用的上述修改後的版本加載項。

+0

謝謝你,你是對的!即使想'status == 0',在'response'中有數據,謝謝!生病粘貼在我使用的解決方案下面。 – Noitidart 2014-08-30 19:06:39

0

感謝@erosman XHR本地文件始終返回狀態0,但其中有數據。所以我修改了我的xhr函數來檢查load是否url的方案是文件uri,如果它的文件uri比它接受請求。

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

謝謝你!它不錯的代碼! – Noitidart 2014-08-31 08:35:36