@shellex说: 对对,他们上辈子都是折翼的新奥尔良鸡翅

Pages

Topics

随便看看

路边社评论员

  • Keith:
    还能用不. »
  • deepblue:
    测试一下浏览器和系统 »
  • abettor:
    “就和CPU特权级别一样”——这的哥难道是Linus的表弟?! »
  • 董英男:
    为什么总提示确认是相册首页呢 到底哪个才是相册首页啊 »
  • kendisk:
    作为一个轻度Linuxer,刚分手后,感觉木有鸭梨。 »
  • MS IE:
    THIS SITE REALLY SUCK! »
  • Alex:
    gnome-women... »
  • liangsuilong:
    GNOME 自己也有鼓励女性参与项目的计划啊.. »
  • infinte:
    对不起,你的“解ban”版本算得有点问题,可以下(9)pp4 测试。ACID3可有95分啊……另外同... »
  • Alex:
    »
  • Randee Saadat:
    Glad you solved your problem, but what is your que... »
  • LinuxRock:
    没想到你也有一台和我一样的破机子......还好现在高三没怎么用,受不了它的发热量.. »

XMLHttpRequest模拟表单上传文件

用XMLHttpRequest以Post方式发送一些表单请求啦,没什么问题。
但是如果表单里面有文件域呢?对这种情况,POST出去的数据不能进行额外编码,否则服务器那边不认识。

看上去w3c没有为XMLHttpRequest发送二进制数据提供支持。不信你可以直接
编造一个含有’\0′的binary_data,然后

xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.send(binary_data);

看看是什么情况。

好吧,我承认这个需求基本上没有什么意义。因为

  • XMLHttpRequest被浏览器限制默认无法跨域。
  • 本域的话用XMLHttpRequest模拟表单上传文件会被人认为是BTer

但是我说Firefox插件Firefox扩展需要。
尽管M$和Mozilla都提供了解决方案:M$的Adobe.stream,Mozilla的XPCOM binary-stream。但是显然,只有Mozilla适合我,否则就是不坚贞,玩着家里的看着外面的,显然,我是好Boy,我知道外面的不干净。
XPCOM,不是XP上的COM,也不是基于XP的发行版,是Mozilla在Netscape的基础上捣鼓出来的一套OOXX。

虽然Gecko被人骂,但是没有这个引擎提供的那一堆零碎,你的Firefox根本玩不转。所以还是感谢一下Mozilla那帮牛B人。

跑题了。

模拟表单发送文件域的关键在于,让XMLHttpRequest能发送2进制串;而发送2进制串的关键呢,nsIBinaryInputStream

代码比较Ugly,意思意思,别在意。

function upload(file) {
    const MULTI		= "@mozilla.org/io/multiplex-input-stream;1";
    const STRINGIS	= "@mozilla.org/io/string-input-stream;1";
    const BINIS     = "@mozilla.org/io/binaryinputstream;1";
    const BOUNDARY  = "-----------------------------19842867121279461543193888023";
    var xhr;
    var url = "http://127.0.0.1/upload.php"

    function infoReceived() {
        var output = xhr.responseText;
        alert(output);
    }
    // binary stream
    var fstream =
        Components.classes["@mozilla.org/network/file-input-stream;1"]
        .createInstance(Components.interfaces.nsIFileInputStream);
    fstream.init(file, -1, -1, false);
    var data_body_stream =
        Components.classes["@mozilla.org/binaryinputstream;1"]
        .createInstance(Components.interfaces.nsIBinaryInputStream);
    data_body_stream.setInputStream(fstream);

    // first boundary and field header
    var data_header = BOUNDARY + '\r\n'
        + 'Content-Disposition: form-data; name="photo1"; filename="'
        + file_name + '"\r\n'
        + 'Content-Type: image/png\r\n\r\n';
    var data_header_stream = Components.classes[STRINGIS]
        .createInstance(Components.interfaces.nsIStringInputStream);
    data_header_stream.setData(data_header, data_header.length);

    // last boundary
    var data_tail = '\r\n' + BOUNDARY + '--\r\n';
    var data_tail_stream = Components.classes[STRINGIS]
        .createInstance(Components.interfaces.nsIStringInputStream);
    data_tail_stream.setData(data_tail, data_tail.length);

    // mix multi-stream
    var mux_stream = Components.classes[MULTI]
        .createInstance(Components.interfaces.nsIMultiplexInputStream);
    mux_stream.appendStream(data_header_stream);
    mux_stream.appendStream(data_body_stream);
    mux_stream.appendStream(data_tail_stream);
    // post
    xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);
    xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + BOUNDARY);
	xhr.setRequestHeader("Content-Length", mux_stream.available() );
    xhr.onload = infoReceived;
    xhr.send(mux_stream);
}

嗯。这个代码着色插件真是好哦。

  1. On November 22, 2008 at 12:36 am
    华华: Mozilla Firefox 3.0.4 / Ubuntu Linux

    FireFox 跨域可以用 js 语句
    netscape.security.PrivilegeManager.enablePrivilege(“UniversalBrowserRead”);
    请求,
    页面会弹出对话框询问用户是否允许

  2. On November 22, 2008 at 12:38 am
    华华: Mozilla Firefox 3.0.4 / Ubuntu Linux

    这行 firefox 地址栏 js 语句,是利用跨域将页面所有图片转为 base64 编码内联图像(本地硬盘、跨域网站等)

    javascript:        var keyStr = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=”;        function encode64(input) {           var output = “”;           var chr1, chr2, chr3;           var enc1, enc2, enc3, enc4;           var i = 0;           do {              chr1 = input.charCodeAt(i++) & 0xff;              chr2 = input.charCodeAt(i++) & 0xff;              chr3 = input.charCodeAt(i++) & 0xff;              enc1 = chr1 >> 2;              enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);              enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);              enc4 = chr3 & 63;              if (isNaN(chr2)) {                 enc3 = enc4 = 64;              } else if (isNaN(chr3)) {                 enc4 = 64;              }              output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +                  keyStr.charAt(enc3) + keyStr.charAt(enc4);           } while (i < input.length);              return output;        };        netscape.security.PrivilegeManager.enablePrivilege(“UniversalBrowserRead”);              for (var i=document.images.length-1; i+1; i–){             img = document.images[i];             if(img.src && !img.src.match(/^data:/)){                 mx = new XMLHttpRequest();                 mx.open(“GET”, img.src, false);                 mx.overrideMimeType(‘text/plain; charset=x-user-defined’);                            mx.send(null);                 if (mx.responseText && (mx.status==200 || mx.status==0) ){                     img.setAttribute(‘uri’, img.src);                     img.src = “data:image;base64,” + encode64(mx.responseText);                 };             }        };        void 0;

Leave a Reply