Ajax.post --> dom.fetch
Ajax.post --> dom.fetch
我正在尝试使用 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")
)
}
}
)
A "ReferenceError: fetch is not defined" 在 js 端抛出,如果替换为 dom.Fetch.fetch
.
我的设置:
新鲜的 jsdom 19.0.0
npm init private
npm install jsdom
project/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 版本工作正常,所以我的节点安装似乎没问题。
从 @Aly here and @armanbilge here 那里获得了关于 Discord 上 scala-js 频道的帮助,他指出:
fetch
在 Node.js 或 JSDOM 中默认不可用,仅在浏览器中可用。
- scala-js-dom 提供对浏览器 APIs 的类型安全访问,而不是 Node.js APIs.
浏览器 API 和节点 API 之间的区别之前我并不清楚,尽管在 scala-js tutorial.
的第 6 步中有详细描述
所以,scala-js-dom.fetch
-dom API 在 运行 浏览器中的 js 程序时有效,但在 运行 时无效使用 Node jsEnv(ironment) 的测试!要获取测试,必须 npm install node-fetch
并使用 node-fetch
,也许通过使用 scala-js 制作外观。
因为我希望我的代码适用于浏览器 (scala-js-dom) 和测试 (Node.js),所以我最终退回到简单地使用 Ajax.post使用 XMLHttpRequest 实现:
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)
}
fetch
API 仅在浏览器环境中默认可用,在 Node 中不可用。 node-fetch
也不会被 jsdom
拉入(或至少不会重新导出),因此 fetch
在当前的 package/environment 设置中不可用。
可能的解决方案:
- 设置 ScalaJS 端,使其在 NodeJS 上调用
node-fetch
,在浏览器上调用 fetch
- 使用在两个平台上都可用的 XMLHttpRequest
(请参阅上下文here in the #scala-js
channel in the Scala Discord for an explanation on why this answer is short. TL;DR, Marc requested I answer here so I can receive the rep. bounty for helping in the Discord. A screenshot。)
我正在尝试使用 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")
)
}
}
)
A "ReferenceError: fetch is not defined" 在 js 端抛出,如果替换为 dom.Fetch.fetch
.
我的设置:
新鲜的 jsdom 19.0.0
npm init private
npm install jsdom
project/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 版本工作正常,所以我的节点安装似乎没问题。
从 @Aly here and @armanbilge here 那里获得了关于 Discord 上 scala-js 频道的帮助,他指出:
fetch
在 Node.js 或 JSDOM 中默认不可用,仅在浏览器中可用。- scala-js-dom 提供对浏览器 APIs 的类型安全访问,而不是 Node.js APIs.
浏览器 API 和节点 API 之间的区别之前我并不清楚,尽管在 scala-js tutorial.
的第 6 步中有详细描述所以,scala-js-dom.fetch
-dom API 在 运行 浏览器中的 js 程序时有效,但在 运行 时无效使用 Node jsEnv(ironment) 的测试!要获取测试,必须 npm install node-fetch
并使用 node-fetch
,也许通过使用 scala-js 制作外观。
因为我希望我的代码适用于浏览器 (scala-js-dom) 和测试 (Node.js),所以我最终退回到简单地使用 Ajax.post使用 XMLHttpRequest 实现:
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)
}
fetch
API 仅在浏览器环境中默认可用,在 Node 中不可用。 node-fetch
也不会被 jsdom
拉入(或至少不会重新导出),因此 fetch
在当前的 package/environment 设置中不可用。
可能的解决方案:
- 设置 ScalaJS 端,使其在 NodeJS 上调用
node-fetch
,在浏览器上调用fetch
- 使用在两个平台上都可用的 XMLHttpRequest
(请参阅上下文here in the #scala-js
channel in the Scala Discord for an explanation on why this answer is short. TL;DR, Marc requested I answer here so I can receive the rep. bounty for helping in the Discord. A screenshot。)