reflex/reflex-dom 的 Xhr 请求
XhrRequest with reflex/reflex-dom
我想执行一个基本的 Ajax 请求,仅此而已。
我在前端使用 reflex
,在后端使用 Scotty
。 Firefox Web 控制台告诉我请求成功,我在那里看到了预期的结果。但是网站从 Just "default"
切换到 Nothing
而不是 Just "success!"
.
这是一个完整的最小示例:
import Reflex (holdDyn)
import Reflex.Dom (button, el, mainWidget, display)
import Reflex.Dom.Xhr (performRequestAsync, xhrRequest, decodeXhrResponse)
import Reflex.Class (tag, constant)
import Data.Default (def)
main :: IO ()
main = do
mainWidget $ el "div" $ do
buttonEvent <- button "click me"
let defaultReq = xhrRequest "GET" "mystring" def --served by Scotty
asyncEvent <- performRequestAsync (tag (constant defaultReq) buttonEvent)
buttonDyn <- holdDyn (Just "default") $ fmap decodeXhrResponse asyncEvent
display buttonDyn
和Scotty
部分:
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.Static
main = scotty 3000 $ do
middleware $ staticPolicy (noDots >-> addBase "/mnt/b/haskell/try-reflex/hello.jsexe")
get "/" $ do
file "/mnt/b/haskell/try-reflex/hello.jsexe/index.html"
get "/mystring" $ html "success!"
由于调试工具告诉我请求成功,我怀疑错误发生在 decodeXhrResponse
附近,但我有点迷茫应该如何继续调试,因为它只是被编译为(不可读)Javascript.
我使用 GitHub 中的 try-reflex Nix 脚本来设置所有内容,并在 Nix 环境中使用 ghcjs hello.hs
进行编译。
编辑:添加 curl
的输出:
$ curl -G http://localhost:3000/mystring
success!%
在 freenode 上 #reflex-frp
的帮助下,我找到了一个解决方案:用 _xhrResponse_body
替换 decodeXhrResponse
并使用 Text
作为默认字符串:
buttonDyn <- holdDyn (Just $ T.pack "default") $ fmap _xhrResponse_body asyncEvent
decodeXhrResponse
期待某种 JSON,虽然我曾尝试通过 Scotty 服务 JSON 但它仍然没有用。
我编写了这个简化的辅助函数,基本上是从反射中检索远程 URL:
curlGet :: MonadWidget t m => Text -> m (Event t Text)
curlGet url = do
let req = xhrRequest "GET" url def
pb <- getPostBuild
asyncReq <- performRequestAsync (tag (constant req) pb)
pure $ fmap (fromMaybe "Unknown error" . _xhrResponse_responseText) asyncReq
我想执行一个基本的 Ajax 请求,仅此而已。
我在前端使用 reflex
,在后端使用 Scotty
。 Firefox Web 控制台告诉我请求成功,我在那里看到了预期的结果。但是网站从 Just "default"
切换到 Nothing
而不是 Just "success!"
.
这是一个完整的最小示例:
import Reflex (holdDyn)
import Reflex.Dom (button, el, mainWidget, display)
import Reflex.Dom.Xhr (performRequestAsync, xhrRequest, decodeXhrResponse)
import Reflex.Class (tag, constant)
import Data.Default (def)
main :: IO ()
main = do
mainWidget $ el "div" $ do
buttonEvent <- button "click me"
let defaultReq = xhrRequest "GET" "mystring" def --served by Scotty
asyncEvent <- performRequestAsync (tag (constant defaultReq) buttonEvent)
buttonDyn <- holdDyn (Just "default") $ fmap decodeXhrResponse asyncEvent
display buttonDyn
和Scotty
部分:
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.Static
main = scotty 3000 $ do
middleware $ staticPolicy (noDots >-> addBase "/mnt/b/haskell/try-reflex/hello.jsexe")
get "/" $ do
file "/mnt/b/haskell/try-reflex/hello.jsexe/index.html"
get "/mystring" $ html "success!"
由于调试工具告诉我请求成功,我怀疑错误发生在 decodeXhrResponse
附近,但我有点迷茫应该如何继续调试,因为它只是被编译为(不可读)Javascript.
我使用 GitHub 中的 try-reflex Nix 脚本来设置所有内容,并在 Nix 环境中使用 ghcjs hello.hs
进行编译。
编辑:添加 curl
的输出:
$ curl -G http://localhost:3000/mystring
success!%
在 freenode 上 #reflex-frp
的帮助下,我找到了一个解决方案:用 _xhrResponse_body
替换 decodeXhrResponse
并使用 Text
作为默认字符串:
buttonDyn <- holdDyn (Just $ T.pack "default") $ fmap _xhrResponse_body asyncEvent
decodeXhrResponse
期待某种 JSON,虽然我曾尝试通过 Scotty 服务 JSON 但它仍然没有用。
我编写了这个简化的辅助函数,基本上是从反射中检索远程 URL:
curlGet :: MonadWidget t m => Text -> m (Event t Text)
curlGet url = do
let req = xhrRequest "GET" url def
pb <- getPostBuild
asyncReq <- performRequestAsync (tag (constant req) pb)
pure $ fmap (fromMaybe "Unknown error" . _xhrResponse_responseText) asyncReq