2017-06-13 24 views
1

我想在Scala.js中使用sendBeacon API並以ByteBuffer的形式發送二進制數據,但我無法將其轉換爲BodyInit。我使用的是boopickle,它生成一個包含我的實例的編碼數據的二進制文件ByteBuffer如何將ByteBuffer轉換爲Scala.js中的BodyInit?

如上所述,我試圖將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]) 

回答

1

TL;博士做此代替:

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

您應該使用typedArray()而不是arrayBuffer(),因爲ArrayBuffer是更低層次的構造,它在Mozilla中不被sendBeacon接受(它接受ArrayBufferView)。

另請注意,arrayBuffer()本身在ByteBuffer上通常沒有意義,因爲ByteBuffer可能只表示底層緩衝區的一部分。您還需要使用arrayBufferOffset()

+0

謝謝!那爲我做了。賞金在2小時內是你的。 –

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) 
+0

不幸的是,這是行不通的。 '[error] found:scala.scalajs.js.typedarray.Int8Array [error] required:org.scalajs.dom.experimental.BodyInit [error](擴展爲)scala.scalajs.js。| [scala.scalajs的.js |。[scala.scalajs.js |。[org.scalajs.dom.raw.Blob,org.scalajs.dom.crypto.BufferSource],org.scalajs.dom.raw.FormData],字符串]'。因爲我使用boopickle,所以我也嘗試了下面的代碼:'Pickle.intoBytes(message).arrayBuffer()。asInstanceOf [BufferSource]',這個編譯,但是將被髮送的有效載荷只是'[object ArrayBuffer]'錯誤。 –

+0

我明白了。在這種情況下,我需要更多的信息來幫助你。請用示例代碼更新您的問題。在目前的狀態下,我無法幫助你,因爲我不知道你在談論什麼確切的API。 – gzm0

+0

據我所知,這只是Scala.js DOM api過時。 fetch規範明確指出'ArrayBuffer'是一個可接受的數據類型。你有沒有嘗試將它投射到'BodyInit'? – gzm0

相關問題