使用reflex

编程入门 行业动态 更新时间:2024-10-17 05:00:05
使用reflex-dom客户端访问服务器服务器(Acess a servant server with a reflex-dom client)

我正在使用0.4版本的reflex-dom而且我有一个很小的反射-dom客户端:

{-# LANGUAGE OverloadedStrings #-} import Reflex.Dom import qualified Data.Text as T import Data.Monoid main :: IO () main = mainWidget body body :: MonadWidget t m => m () body = el "div" $ do pb <- getPostBuild snd <- button "Send" -- Use one of the following URL's: let defReq = "http://localhost:8080/name/3" -- let defReq = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY" let req = XhrRequest "GET" defReq (def {_xhrRequestConfig_sendData = defReq} ) let evReq = tagPromptlyDyn (constDyn req) snd evRsp <- performRequestAsync evReq let evResult = (result . _xhrResponse_responseText) <$> evRsp el "p" $ return () dynText =<< holdDyn "NOPE" evResult return () result :: Show a => Maybe a -> T.Text result (Just x) = "Received: " <> T.pack (show x) result Nothing = "Response is Nothing"

如XhrRequest with reflex / reflex-dom中所述 ,我使用_xhrResponse_responseText而不是decodeXhrResponse

当我使用NASA URL运行此客户端时,它会显示一个不错的JSON字符串。 因此,我认为,这个反射dom客户端正在工作。

我也有一个小仆人服务器:

{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} import Servant import Servant.API import Servant.Server import Network.Wai import Network.Wai.Handler.Warp import Network.Wai.Logger (withStdoutLogger) import qualified Data.Text as T main :: IO () main = withStdoutLogger $ \aplogger -> do let settings = setPort 8080 $ setLogger aplogger defaultSettings runSettings settings app app :: Application app = serve userAPI server userAPI :: Proxy API -- API usage: http://localhost:8080/name/2 userAPI = Proxy type API = "name" :> Capture "pid" Int :> Get '[PlainText] T.Text server :: Server API server = name name :: Monad m => Int -> m T.Text name pid = return $ nameById pid nameById :: Int -> T.Text nameById 1 = "Isaac Newton" nameById 2 = "Galileo Galilei" nameById 3 = "Marie Curie" nameById _ = "UNKNOWN!!"

当我在浏览器中使用http://localhost:8080/name/3或curl访问此服务器时,我看到了预期的结果Marie Curie 。 因此我假设,这个servant服务器正在工作。

当我使用localhost的URL运行上面的reflex-dom客户端时,我可以在服务器的stdout日志中看到请求,但客户端不显示Marie Curie的名称。 相反,客户端只显示一个空字符串! 所以作为一个团队,客户端和服务器不能一起工作! 为什么?

I'm using version 0.4 of reflex-dom and I have a tiny reflex-dom client:

{-# LANGUAGE OverloadedStrings #-} import Reflex.Dom import qualified Data.Text as T import Data.Monoid main :: IO () main = mainWidget body body :: MonadWidget t m => m () body = el "div" $ do pb <- getPostBuild snd <- button "Send" -- Use one of the following URL's: let defReq = "http://localhost:8080/name/3" -- let defReq = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY" let req = XhrRequest "GET" defReq (def {_xhrRequestConfig_sendData = defReq} ) let evReq = tagPromptlyDyn (constDyn req) snd evRsp <- performRequestAsync evReq let evResult = (result . _xhrResponse_responseText) <$> evRsp el "p" $ return () dynText =<< holdDyn "NOPE" evResult return () result :: Show a => Maybe a -> T.Text result (Just x) = "Received: " <> T.pack (show x) result Nothing = "Response is Nothing"

As described in XhrRequest with reflex/reflex-dom, I'm using _xhrResponse_responseText and not decodeXhrResponse.

When I run this client with the NASA URL, it displays a nice JSON string. Therefore I assume, this reflex-dom client is working.

I have a tiny servant server too:

{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} import Servant import Servant.API import Servant.Server import Network.Wai import Network.Wai.Handler.Warp import Network.Wai.Logger (withStdoutLogger) import qualified Data.Text as T main :: IO () main = withStdoutLogger $ \aplogger -> do let settings = setPort 8080 $ setLogger aplogger defaultSettings runSettings settings app app :: Application app = serve userAPI server userAPI :: Proxy API -- API usage: http://localhost:8080/name/2 userAPI = Proxy type API = "name" :> Capture "pid" Int :> Get '[PlainText] T.Text server :: Server API server = name name :: Monad m => Int -> m T.Text name pid = return $ nameById pid nameById :: Int -> T.Text nameById 1 = "Isaac Newton" nameById 2 = "Galileo Galilei" nameById 3 = "Marie Curie" nameById _ = "UNKNOWN!!"

When I access this server in the browser with http://localhost:8080/name/3 or with curl, I see the expected result Marie Curie. Therefore I assume, this servant server is working.

When I run the above reflex-dom client with the URL of the localhost, I can see the request in the stdout log of the server, but the client does NOT display the name of Marie Curie. Instead the client just displays an empty string! So as a team, the client and the server do not work together! Why?

最满意答案

您可能正在看到跨源资源共享(CORS)问题。 您可以通过检查浏览器控制台以查看如下错误来验证此信息(至少在chrome中):

XMLHttpRequest无法加载http:// localhost:8080 / name / 3 。 请求的资源上不存在“Access-Control-Allow-Origin”标头。 因此不允许Origin'http:// localhost:8000 '访问。

如果是这种情况,您可以通过替换此行来启用服务器中的CORS:

app = serve userAPI server

用这一行:

app = simpleCors (serve userAPI server)

您需要导入wai-cors:

import Network.Wai.Middleware.Cors

这是您的servant服务器,包含以下更改:

{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} import Servant import Servant.API import Servant.Server import Network.Wai import Network.Wai.Handler.Warp import Network.Wai.Logger (withStdoutLogger) import Network.Wai.Middleware.Cors import qualified Data.Text as T main :: IO () main = withStdoutLogger $ \aplogger -> do let settings = setPort 8080 $ setLogger aplogger defaultSettings runSettings settings app app :: Application app = simpleCors (serve userAPI server) userAPI :: Proxy API -- API usage: http://localhost:8080/name/2 userAPI = Proxy type API = "name" :> Capture "pid" Int :> Get '[PlainText] T.Text server :: Server API server = name name :: Monad m => Int -> m T.Text name pid = return $ nameById pid nameById :: Int -> T.Text nameById 1 = "Isaac Newton" nameById 2 = "Galileo Galilei" nameById 3 = "Marie Curie" nameById _ = "UNKNOWN!!"

You probably are seeing Cross-Origin Resource Sharing (CORS) problems. You can verify this (in chrome at least) by checking your browser console for an error that looks like this:

XMLHttpRequest cannot load http://localhost:8080/name/3. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.

If this is the case, you can enable CORS in your server by replacing this line :

app = serve userAPI server

with this line:

app = simpleCors (serve userAPI server)

You will need to import wai-cors:

import Network.Wai.Middleware.Cors

here is your servant server with these changes:

{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} import Servant import Servant.API import Servant.Server import Network.Wai import Network.Wai.Handler.Warp import Network.Wai.Logger (withStdoutLogger) import Network.Wai.Middleware.Cors import qualified Data.Text as T main :: IO () main = withStdoutLogger $ \aplogger -> do let settings = setPort 8080 $ setLogger aplogger defaultSettings runSettings settings app app :: Application app = simpleCors (serve userAPI server) userAPI :: Proxy API -- API usage: http://localhost:8080/name/2 userAPI = Proxy type API = "name" :> Capture "pid" Int :> Get '[PlainText] T.Text server :: Server API server = name name :: Monad m => Int -> m T.Text name pid = return $ nameById pid nameById :: Int -> T.Text nameById 1 = "Isaac Newton" nameById 2 = "Galileo Galilei" nameById 3 = "Marie Curie" nameById _ = "UNKNOWN!!"

更多推荐

本文发布于:2023-07-15 05:43:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1110757.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:reflex

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!