2014-08-30 6 views
0

Это не дает результата 0 вместо 200. Я уверен, что это связано с тем, что xmlhttprequests не разрешено обращаться к локальному диску, но это должно применяться только к веб-области, а не к области 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 для доступа к файлу: // URL- request.status не правильно установлен в 200, чтобы указать успех. В таких случаях request.readyState == 4, request.status == 0 и request.response будет оцениваться как true.

Update:

Лично я хотел бы использовать 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

0

Благодаря @erosman XHR в локальный файл всегда возвращает статус 0, но в нем есть данные. Поэтому я изменил свою функцию xhr, чтобы проверить загрузку, если схема 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

Смежные вопросы