我正在嘗試使用 dom.fetch(或 dom.Fetch.fetch)api 而不是 Ajax.post 并且有一些問題:
這是從 ajax 到 fetch 的正確翻譯嗎?
Ajax.post(
url = "http://localhost:8080/ajax/myMethod",
data = byteBuffer2typedArray(Pickle.intoBytes(req.payload)),
responseType = "arraybuffer",
headers = Map("Content-Type" -> "application/octet-stream"),
)
dom.fetch(
"http://localhost:8080/fetch/myMethod",
new RequestInit {
method = HttpMethod.POST
body = byteBuffer2typedArray(Pickle.intoBytes(req.payload))
headers = new Headers {
js.Array(
js.Array("Content-Type", "application/octet-stream")
)
}
}
)
但是,在 js 端會拋出“ReferenceError: fetch is not defined”,如果替換為dom.Fetch.fetch.
我的設定:
新鮮的 jsdom 19.0.0
npm init private
npm install jsdom
專案/plugins.sbt
libraryDependencies = "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0"
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.8.0")
build.sbt(在js專案中)
libraryDependencies = "org.scala-js" %%% "scalajs-dom" % "2.0.0"
jsEnv := new JSDOMNodeJSEnv(JSDOMNodeJSEnv.Config()
.withArgs(List("--dns-result-order=ipv4first")))
認為 Scala.js 1.8 不需要 jsEnv 解決方法(參見https://github.com/scala-js/scala-js-js-envs/issues/12#issuecomment-958925883)。但是當我運行ajax版本時仍然需要它。通過變通方法,我的 ajax 版本作業正常,所以我的節點安裝似乎沒問題。
uj5u.com熱心網友回復:
該fetchAPI 僅在瀏覽器環境中默認可用,在 Node.js 中不可用。node-fetch也不會被 拉入(或至少不會重新匯出)jsdom,因此fetch在當前包/環境設定中不可用。
可能的解決方案:
- 將 ScalaJS 朝上設定,以便在 NodeJS
node-fetch和fetch瀏覽器上呼叫 - 使用在兩個平臺上都可用的 XMLHttpRequest
(請在 Scala Discord的頻道中查看這里,以#scala-js了解為什么這個答案很短。TL;DR,Marc 要求我在這里回答,以便我可以獲得代表在 Discord 中提供幫助的賞金。背景關系的螢屏截圖是可用的。)
uj5u.com熱心網友回復:
得到了來自@Aly上齟齬階-JS渠道幫助這里和@armanbilge這里誰指出:
fetch默認情況下在 Node.js 或 JSDOM 中不可用,僅在瀏覽器中可用。- scala-js-dom 提供對瀏覽器 API 的型別安全訪問,而不是 Node.js API。
我之前并不清楚瀏覽器 API 和 Node API 之間的區別,盡管在scala-js 教程的第 6 步中對其進行了很好的描述。
因此,dom.fetchscala-js-dom API 在瀏覽器中運行 js 程式時有效,但在運行使用 Node jsEnv(ironment) 的測驗時無效!要在測驗中獲取npm install node-fetch并使用node-fetch,也許通過使用 scala-js 制作外觀。
由于我希望我的代碼同時適用于瀏覽器 (scala-js-dom) 和測驗 (Node.js),我最終退回到簡單地使用 XMLHttpRequest 的 Ajax.post 實作:
case class PostException(xhr: dom.XMLHttpRequest) extends Exception {
def isTimeout: Boolean = xhr.status == 0 && xhr.readyState == 4
}
val url = s"http://$interface:$port/ajax/" slothReq.path.mkString("/")
val byteBuffer = Pickle.intoBytes(slothReq.payload)
val requestData = byteBuffer.typedArray().subarray(byteBuffer.position, byteBuffer.limit)
val req = new dom.XMLHttpRequest()
val promise = Promise[dom.XMLHttpRequest]()
req.onreadystatechange = { (e: dom.Event) =>
if (req.readyState == 4) {
if ((req.status >= 200 && req.status < 300) || req.status == 304)
promise.success(req)
else
promise.failure(PostException(req))
}
}
req.open("POST", url) // (I only need to POST)
req.responseType = "arraybuffer"
req.timeout = 0
req.withCredentials = false
req.setRequestHeader("Content-Type", "application/octet-stream")
req.send(requestData)
promise.future.recover {
case PostException(xhr) =>
val msg = xhr.status match {
case 0 => "Ajax call failed: server not responding."
case n => s"Ajax call failed: XMLHttpRequest.status = $n."
}
println(msg)
xhr
}.flatMap { req =>
val raw = req.response.asInstanceOf[ArrayBuffer]
val dataBytes = TypedArrayBuffer.wrap(raw.slice(1))
Future.successful(dataBytes)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/388236.html
