nsIXMLHttpRequest 编辑
Obsolete since Gecko 60 (Firefox 60 / Thunderbird 60 / SeaMonkey 2.57)
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.
nsIXMLHttpRequest
along with nsIJSXMLHttpRequest
and nsIXMLHttpRequestEventTarget
are Mozilla's implementation details of the DOM XMLHttpRequest object.
This page contains documentation, specific to Mozilla application and add-on developers.
The interface definition: https://dxr.mozilla.org/mozilla-central/source/dom/xhr/nsIXMLHttpRequest.idl
Elevated Privileges
As mentioned in the "Non-Standard Properties" the property of channel
was read-only. When using the XPCOM interface, as seen below in Example 2, we can get access to this. The most obvious benefit is that we can set nsiRequest - Constants in the xhr.channel.loadFlags
. For instance, as done in Example 2, the flag of LOAD_ANONYMOUS
is added, this strips all user data (cookies, tokens, etc).
Using event handlers from native code
(Not sure if it's up-to-date)
From native code, the way to set up onload and onerror handlers is a bit different. Here is a comment from Johnny Stenback <jst@netscape.com>:
The mozilla implementation of nsIXMLHttpRequest implements the interface nsIDOMEventTarget and that's how you're supported to add event listeners. Try something like this: nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(myxmlhttpreq)); target->AddEventListener(NS_LITERAL_STRING("load"), mylistener, PR_FALSE) where mylistener is your event listener object that implements the interface nsIDOMEventListener. The 'onload', 'onerror', and 'onreadystatechange' attributes moved to nsIJSXMLHttpRequest, but if you're coding in C++ you should avoid using those.
Though actually, if you use addEventListener from C++ weird things will happen too, since the result will depend on what JS happens to be on the stack when you do it....
Conclusion: Do not use event listeners on XMLHttpRequest from C++, unless you're aware of all the security implications. And then think twice about it.
Example code
This is a simple example code for opening a simple HTTP request from a xul application (like a Mozilla extension) without using observers:
var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(); req.open('POST', "http://www.foo.bar:8080/nietzsche.do", true); req.send('your=data&and=more&stuff=here');
Example 2
var {Cu: utils, Cc: classes, Ci: instances} = Components;
Cu.import('resource://gre/modules/Services.jsm');
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);
}
xhr('https://www.wenjiangs.com/wp-content/uploads/2020/mozilla/1-col-layout-alt.png");
var promised = OS.File.writeAtomic(file, new UInt8Array(data));
promised.then(
function() {
alert('succesfully saved image to desktop')
},
function(ex) {
alert('FAILED in saving image to desktop')
}
);
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论