使用JavaScript从二进制文件中读取字节,无需使用jQuery

3

我正在尝试制作一个JavaScript仿真器,并且希望它非常轻巧,所以我不想使用jQuery和jDataView加载“ROMs”。因此,我用纯JS编写了自己的ROM加载器。

它运行得非常好(多亏了这个网站上的许多主题),但是在IE上仍然存在问题,我在其他地方找不到任何帮助。

这是我的JS代码:

/**
* @param file - the path or URL of the ROM file to load. The file must be served with the Mime-Type: 'text/plain; charset=x-user-defined'
* @param callback - a function to call when the loading is complete. Its first parameter contains an array of numbers representing the ROM bytes.
*/
function loadRom(file, callback)
{
  var xhr = new XMLHttpRequest();                             // AJAX loader
  xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){                                  // When the file content is received
      var str = xhr.responseText;                             // Store it as a string
      var ch, bytes = [];
      for (var i = 0; i < str.length; i++){
        ch = str.charCodeAt(i);                               // Read each character
        bytes.push(ch & 0xFF);                                // Store the last byte of the character
      }
      callback(bytes);                                        // Call the callback function with bytes as parameter
    }
  };
  xhr.open("GET", file, true);                                // Load the file
  xhr.send(null);                                             // Send the AJAX request
}

// Test
var mem=[];
loadRom("TEST.ch8", function(m){
  for(i=0;i<m.length;i++)console.log(m[i].toString(16))                 // Log each byte in hexa
});

这是我的.htaccess文件(chip8的ROM文件扩展名为.ch8):
AddType 'text/plain; charset=x-user-defined' ch8

这是我的测试ROM(包含0x00到0xFF字节): http://www.filedropper.com/test_16 测试结果如下:
Firefox和Chrome工作正常:它们记录了从0x00到0xFF的每个字节。
IE9也一样,除了0x80到0x9F之间的32个字节,这些字节被替换成完全不相关的数字。(即使比较二进制代码,也没有明显的转换逻辑)
所以我的问题是:
1. IE9对这些字节做了什么? 2. 我该如何解决这个问题?
谢谢你们的想法(或解决方案)!
Max。

我已经在为自己的目的玩弄你的代码片段,如果你不介意的话,但是遇到了一些问题:http://stackoverflow.com/questions/22576518 - Fedor Alexander Steeman
2个回答

1
我終於找到了答案:
  • IE會轉換這些字符,無論你怎麼做。

  • 但它提供了一種直接將AJAX響應導出為字節數組的方法,這幾乎比其他瀏覽器更酷

    var bytes = VBArray(xhr.responseBody).toArray(); //僅限IE!

因此,這是一個將文件轉換為字節數組的功能,支持IE7!

function loadRom(path, memory, callback)
{
  var i = 0,                                                                                        // Loop iterator
      ie /*@cc_on=1@*/,                                                                             // IE detection with conditional compilation
      xhr = new XMLHttpRequest;                                                                     // XHR object
  xhr.onreadystatechange = function(){                                                              // When the XHR object state changes
    if(xhr.readyState > 3){                                                                         // When the file is received (readyState 4)
      for(xhr = ie ? VBArray(xhr.responseBody).toArray() : xhr.responseText; i < xhr.length; i++){  // Get the response text as a bytes array (on IE) or a string (on other browsers) and iterate
        memory.push(ie ? xhr[i] : xhr.charCodeAt(i) & 0xFF);                                        // Store in memory the byte (on IE) or the last byte of the character code (on other browsers)
      }
      callback()                                                                                    // Call the callback function
    }
  }
  xhr.open("GET", path);                                                                            // Load the file
  xhr.send()                                                                                        // Send the XHR request
}

VBArray 可能不是你想使用的东西。现在 JS 有了类型化数组,并且各种浏览器都支持它们。请参见 http://www.html5rocks.com/en/tutorials/file/xhr2/。 - ebidel

1
你有没有考虑对数据进行base-64编码,并在客户端解码?

是的,我看过并考虑过涉及base64和/或PHP的解决方案,但我想要一个纯JS的解决方案。或者至少解释一下在IE9中发生了什么,为这些字符做出解释。 - Maxime E
你可以在Javascript中解码base64。请参考https://dev59.com/8nE85IYBdhLWcg3wXCEv获取示例。不过,我很高兴你找到了可行的方法。 - Erin Stanfill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接