Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Javascript和XMLHttpRequest加载二进制图像数据?_Javascript_Image_Xmlhttprequest - Fatal编程技术网

如何使用Javascript和XMLHttpRequest加载二进制图像数据?

如何使用Javascript和XMLHttpRequest加载二进制图像数据?,javascript,image,xmlhttprequest,Javascript,Image,Xmlhttprequest,我试图加载一个映像客户端,并对服务器返回的字节进行base64编码,以便将其传递给执行一些处理。IE具有XMLHttpRequest对象的RequestBody属性,但我似乎无法使用它,RequestText被截断。在Firefox中,RequestText存在,但似乎已损坏。您可以让服务器返回base64文本,而不是对客户端进行编码 例如,(在ASP.NET中)对/ImageAsBase64.ashx?file=/images/myimage.png的请求可以进行编码,以读取该文件,对其进行B

我试图加载一个映像客户端,并对服务器返回的字节进行base64编码,以便将其传递给执行一些处理。IE具有XMLHttpRequest对象的RequestBody属性,但我似乎无法使用它,RequestText被截断。在Firefox中,RequestText存在,但似乎已损坏。

您可以让服务器返回base64文本,而不是对客户端进行编码

例如,(在ASP.NET中)对/ImageAsBase64.ashx?file=/images/myimage.png的请求可以进行编码,以读取该文件,对其进行Base64编码,并将其作为响应流传输


在PHP或其他任何应用程序中,这都是一样的。

如果您使用COTS,您可以设置一个中间网关,在返回到客户端之前,在该网关中发出请求并将其转换(本例中为base64编码)为更令人满意的内容。

我是这样做的

这项技术是在回答另一个SO问题时提供的,但在这里也是相关的

我不想对任何东西进行base64编码。我想通过Javascript在浏览器中下载和解析二进制文件,而无需修改服务器对其进行专门编码。我发现在Firefox中,通过
OverrideMetype()
强制响应的mimetype,我可以使用
XMLHttpRequest.responseText
。在IE上,这是不同的,因为:

  • IE上的
    responseText
    在第一个零处截断。对于二进制流,这是一个大问题

  • 没有
    XMLHttpRequest.overrideMimeType()
    ,强制IE将二进制流视为文本

  • 虽然有一个专门设计用于二进制数据流的
    XMLHttpRequest.responseBody
    (仅限IE!),但令人恼火的是,该属性无法从Javascript中使用

因此,需要将IE的
responseBody
属性转换为类似FireFox中的
responseText
属性,并使用mime类型强制。这可以使用注入的VBScript实现

要使其跨浏览器,只需将特定于浏览器的逻辑打包到条件中即可。这就是我使用的:

// one-time code
if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
    var IEBinaryToArray_ByteStr_Script =
    "<!-- IEBinaryToArray_ByteStr -->\r\n"+
    "<script type='text/vbscript'>\r\n"+
    "Function IEBinaryToArray_ByteStr(Binary)\r\n"+
    "   IEBinaryToArray_ByteStr = CStr(Binary)\r\n"+
    "End Function\r\n"+
    "Function IEBinaryToArray_ByteStr_Last(Binary)\r\n"+
    "   Dim lastIndex\r\n"+
    "   lastIndex = LenB(Binary)\r\n"+
    "   if lastIndex mod 2 Then\r\n"+
    "       IEBinaryToArray_ByteStr_Last = Chr( AscB( MidB( Binary, lastIndex, 1 ) ) )\r\n"+
    "   Else\r\n"+
    "       IEBinaryToArray_ByteStr_Last = "+'""'+"\r\n"+
    "   End If\r\n"+
    "End Function\r\n"+
    "</script>\r\n";

    // inject VBScript
    document.write(IEBinaryToArray_ByteStr_Script);
}


// each time you make a request for a binary resource:
var req = (function() {
    if (window.XMLHttpRequest) {
        return new window.XMLHttpRequest();
    }
    else {
        try {
            return new ActiveXObject("MSXML2.XMLHTTP");
        }
        catch(ex) {
            return null;
        }
    }
})();

var fileContents = "";
var filesize = -1;
var readByteAt = function(i){
    return fileContents.charCodeAt(i) & 0xff;
};

req.open("GET", url, true);

if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
    // IE-specific logic here
    // helper to convert from responseBody to a "responseText" like thing
    var convertResponseBodyToText = function (binary) {
        var byteMapping = {};
        for ( var i = 0; i < 256; i++ ) {
            for ( var j = 0; j < 256; j++ ) {
                byteMapping[ String.fromCharCode( i + j * 256 ) ] =
                    String.fromCharCode(i) + String.fromCharCode(j);
            }
        }
        var rawBytes = IEBinaryToArray_ByteStr(binary);
        var lastChr = IEBinaryToArray_ByteStr_Last(binary);
        return rawBytes.replace(/[\s\S]/g,
                                function( match ) { return byteMapping[match]; }) + lastChr;
    };

    req.setRequestHeader("Accept-Charset", "x-user-defined");
    req.onreadystatechange = function(event){
        if (req.readyState == 4) {
            if (req.status == 200) {
                fileContents = convertResponseBodyToText(req.responseBody);
                fileSize = fileContents.length-1;
                // invoke a callback here, if you like...
            }
            else{
                alert("download failed, status " + req.status);
            }
        }
    };
    req.send();

} else {
    // ff/Gecko/Webkit specific stuff here
    req.onreadystatechange = function(aEvt) {
        if (req.readyState == 4) { // completed
            if(req.status == 200){ // status == OK
                fileContents = binStream.req.responseText;
                filesize = fileContents.length;
                // invoke a callback here, if you like...
            }
            else {
                alert("download failed, status " + req.status);
            }
        }
    };
    // coerce response type
    req.overrideMimeType('text/plain; charset=x-user-defined');
    req.send(null);
}
//一次性代码
if(/msie/i.test(navigator.userAgent)和&!/opera/i.test(navigator.userAgent)){
var IEBinaryToArray\u ByteStr\u脚本=
“\r\n”+
“\r\n”+
“函数IEBinaryToArray\u ByteStr(二进制)\r\n”+
“IEBinaryToArray\u ByteStr=CStr(二进制)\r\n”+
“结束函数\r\n”+
“函数IEBinaryToArray\u ByteStr\u Last(二进制)\r\n”+
“Dim lastIndex\r\n”+
“lastIndex=LenB(二进制)\r\n”+
“如果lastIndex mod 2,则\r\n”+
IEBinaryToArray\u ByteStr\u Last=Chr(AscB(MidB(二进制,lastIndex,1)))\r\n+
“否则\r\n”+
“IEBinaryToArray\u ByteStr\u Last=“+”“”“+”+”\r\n”+
“如果结束\r\n”+
“结束函数\r\n”+
“\r\n”;
//注入VBScript
编写(IEBinaryToArray\u ByteStr\u脚本);
}
//每次请求二进制资源时:
var req=(函数(){
if(window.XMLHttpRequest){
返回新的window.XMLHttpRequest();
}
否则{
试一试{
返回新的ActiveXObject(“MSXML2.XMLHTTP”);
}
捕获(ex){
返回null;
}
}
})();
var fileContents=“”;
var filesize=-1;
var readByteAt=函数(i){
返回fileContents.charCodeAt(i)&0xff;
};
请求打开(“获取”,url,true);
if(/msie/i.test(navigator.userAgent)和&!/opera/i.test(navigator.userAgent)){
//IE的特定逻辑在这里
//帮助程序从responseBody转换为类似“responseText”的内容
var CONVERTEBODYTOTEXT=函数(二进制){
var byteMapping={};
对于(变量i=0;i<256;i++){
对于(var j=0;j<256;j++){
byteMapping[String.fromCharCode(i+j*256)]=
String.fromCharCode(i)+String.fromCharCode(j);
}
}
var rawBytes=IEBinaryToArray_ByteStr(二进制);
var lastChr=IEBinaryToArray\u ByteStr\u Last(二进制);
返回rawBytes.replace(/[\s\s]/g,
函数(match){returnbytemapping[match];})+lastChr;
};
请求setRequestHeader(“接受字符集”、“x-用户定义”);
req.onreadystatechange=函数(事件){
如果(req.readyState==4){
如果(请求状态==200){
fileContents=convertResponseBodyToText(请求responseBody);
fileSize=fileContents.length-1;
//在这里调用回调,如果您喜欢。。。
}
否则{
警报(“下载失败,状态”+请求状态);
}
}
};
请求发送();
}否则{
//ff/Gecko/Webkit特定的东西在这里
req.onreadystatechange=功能(aEvt){
如果(req.readyState==4){//已完成
如果(req.status==200){//status==OK
fileContents=binStream.req.responseText;
filesize=fileContents.length;
//在这里调用回调,如果您喜欢。。。
}
否则{
警报(“下载失败,状态”+请求状态);
}
}
};
//强制响应类型
req.overrideMimeType('text/plain;charset=x-user-defined');
请求发送(空);
}
…然后调用
readByte(i)
以获取二进制文件中第i个位置的字节

祝你好运


对于VBScript转换逻辑。

不幸的是,在这种情况下,这不起作用-我需要一些COTS软件的数据,但它没有base64选项;然而,这些图像是特定于用户会话的,我无法伪造软件,以为服务器是同一个用户会话的一部分。经过几天的努力,我能够做到这一点,尽管互联网上关于进行这种二进制操作的信息相当多