我想在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])
答案 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()
。