如何在Scala.js中将ByteBuffer转换为BodyInit?

时间:2017-06-13 13:29:18

标签: scala scala.js

我想在Scala.js中使用sendBeacon API并以ByteBuffer的形式发送二进制数据,但我无法将其转换为BodyInit。我正在使用boopickle生成包含我的实例的编码数据的二进制ByteBuffer

根据建议,我尝试将ByteBuffer转换为ArrayBuffer并将其转换为BodyInit。但是,在Firefox 53.0.3上运行此代码时,我没有收到运行时错误,而是有效负载仅包含[object ArrayBuffer]而不包含二进制数据本身。

以下是代码:

import scala.scalajs.js.typedarray.TypedArrayBufferOps._
import boopickle.Default._
import org.scalajs.dom.experimental.BodyInit
import org.scalajs.dom.experimental.beacon._   

case class Message(firstName: String, lastName: String)
val message = Message("John", "Doe")
val data = Pickle.intoBytes(message).arrayBuffer()
dom.window.navigator.sendBeacon("/api", data.asInstanceOf[BodyInit])

2 个答案:

答案 0 :(得分:2)

在Scala.js中,直接ByteBuffers由TypedArrays支持。

因此,当您分配ByteBuffer时,请确保它是直接的:

val buf = ByteBuffer.allocateDirect(1024)

然后,您可以使用TypedArrayBufferOps来访问基础TypedArray

import scala.scalajs.js.typedarray.TypedArrayBufferOps._
sendBeacon("http://foo.bar/", buf.typedArray)

答案 1 :(得分:1)

tl; dr这样做:

val data = Pickle.intoBytes(message).typedArray()
dom.window.navigator.sendBeacon("/api", data.asInstanceOf[BodyInit])

您应该使用typedArray()而不是arrayBuffer(),因为ArrayBuffer是Mozilla中sendBeacon不接受的更低级别的构造(它接受ArrayBufferView }})。

另请注意,arrayBuffer()ByteBuffer本身通常没有意义,因为ByteBuffer可能只代表底层缓冲区的一部分。您还需要使用arrayBufferOffset()