通过 HTTP 在 JavaScript 中发送二进制数据

IT技术 javascript ajax binary hex
2021-01-21 01:36:00

我正在尝试向网络上的设备发送 HTTP POST。不幸的是,我想向设备发送四个特定字节的数据,我似乎只能向设备发送字符串。反正有没有使用javascript发送原始二进制文件?

这是我用来执行 POST 的脚本,它目前不会运行,除非我在数据字段中放入一个字符串。有任何想法吗?

(function ($) {
   $.ajax({
      url: '<IP of Address>',
      type: 'POST',
      contentType: 'application/octet-stream',

      //data:'253,0,128,1',
      data:0xFD008001,

      crossDomain: true
   });
})(jQuery);
4个回答

默认情况下,jQuery 序列化数据(在data属性中传递) - 这意味着0xFD008001 数字作为 '4244668417'字符串(10 个字节,而不是 4 个)传递给服务器,这就是服务器未按预期处理它的原因。

有必要通过将$.ajax属性设置processData来防止这种行为false

默认情况下,作为对象传递给 data 选项的数据(从技术上讲,除了字符串之外的任何内容)将被处理并转换为查询字符串,适合默认的内容类型“application/x-www-form-urlencoded” . 如果要发送 DOMDocument 或其他未处理的数据,请将此选项设置为 false。

...但这只是整个故事的一部分:XMLHttpRequest.send实施有其自身的限制这就是为什么你最好的选择是使用TypedArrays制作你自己的序列化器

// Since we deal with Firefox and Chrome only 
var bytesToSend = [253, 0, 128, 1],
    bytesArray = new Uint8Array(bytesToSend);

$.ajax({
   url: '%your_service_url%',
   type: 'POST',
   contentType: 'application/octet-stream',  
   data: bytesArray,
   processData: false
});

或者根本不使用 jQuery:

var bytesToSend = [253, 0, 128, 1],
    bytesArray = new Uint8Array(bytesToSend);

var xhr = new XMLHttpRequest();
xhr.open('POST', '%your_service_url%');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.send(bytesArray);
我得到ArrayBuffer is deprecated in XMLHttpRequest.send(). Use ArrayBufferView instead.但后来得到一个ReferenceError: ArrayBufferView is not defined
2021-03-15 01:36:00
谢谢你!我对 javascript 很陌生,所以我想我错过了一些简单的东西。你的解释绝对超越了。谢谢!
2021-03-15 01:36:00
是的,我已经将其重写为不使用ArrayBuffer; Chrome 和 Firefox 实际上都支持 typedArray 作为xhr.send参数。
2021-03-20 01:36:00
不需要你上面的循环。类型化数组构造函数接受类数组对象并为您执行循环。所以这var bytesArray = new Uint8Array(bytesToSend);就是你所需要的。详细信息在这里,但我不想单方面编辑它。
2021-03-30 01:36:00
我明白你的意思,但是浏览器支持呢?我假设使用new TypedArray(plainArray)构造仅在支持 的浏览器中是可能的TypedArray.from(plainArray),并且从这个 docpage判断,IE 和 Safari 不允许这样做。
2021-04-11 01:36:00

您可以使用 xhr2 通过 ajax 发送二进制数据,您可以将数据作为类型化数组或blob 发送

(function ($) {
   var data = new Uint32Array(1);
   data[0] = 0xFD008001; 
   $.ajax({
      url: '<IP of Address>',
      type: 'POST',
      contentType: false,
      processData: false,
      //data:'253,0,128,1',
      data:data,

      crossDomain: true
   });
})(jQuery);

https://developer.mozilla.org/en-US/docs/Web/API/Uint32Array

好吧,我并没有将其视为字节序列,而是将其视为 u32 int。
2021-03-30 01:36:00
+1,但这实际上以相反的顺序发送字节。)
2021-04-13 01:36:00

您可以将 ArrayBuffer 类型的数据转换为 ArrayBufferView,如下所示:

var fileContent = new DataView(<ArrayBuffer_data>);

有了这个,您在发送文件内容时不会在控制台中收到警告。

你可以使用atob()btoa()

var data = new Uint32Array(1);
data[0] = 0xFD008001;
atob(data)

这会将您的二进制数据转换为可以作为文本发送的 base64 字符串。