问题描述
我使用的是反射式dom版本0.4,我有一个小型反射式客户端:
{ - # LANGUAGE OverloadedStrings# - }
导入Reflex.Dom
将合格的Data.Text导入为T
导入Data.Monoid
main :: IO()
main = mainWidget body
body :: MonadWidget tm => m()
body = eldiv$ do
pb< - getPostBuild
snd< - button发送
- 使用以下URL之一:
让defReq =http:// localhost:8080 / name / 3
- let defReq =https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY
let req = XhrRequestGETdefReq(def {_xhrRequestConfig_sendData = defReq})
let evReq = tagPromptlyDyn(constDyn req)snd
evRsp< - performRequestAsync evReq
let evResult =(result。 _xhrResponse_responseText)< $> evRsp
elp$ return()
dynText =<< holdDynNOPEevResult
return()
result ::显示a =>也许是 - > T.Text
result(Just x)=Received:<> T.pack(show x)
result Nothing =Response is Nothing
如上所述在中,我正在使用 _xhrResponse_responseText 而不是 decodeXhrResponse 。
当我使用NASA URL运行这个客户端时,它显示一个很好的JSON字符串。因此,我认为,这个反射客户端工作正常。
我也有一个小型服务器服务器:
<$ p $ b $ {$#c $ { - #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)
将合格的Data.Text导入为T
main :: IO()
main = withStdoutLogger $ \aplogger - >做
让settings = setPort 8080 $ setLogger aplogger defaultSettings
runSettings设置app
app :: Application
app = serve userAPI server
userAPI :: Proxy API - API用法:http:// localhost:8080 / name / 2
userAPI =代理
类型API =name:>捕获pidInt:> 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
。因此,我认为,这个服务器服务器正在工作。
当我使用localhost的URL运行上述reflex-dom客户端时,我可以在标准输出日志中看到请求,但客户端 NOT 显示 Marie Curie 的名称。相反,客户端只显示一个空字符串!
作为一个团队,客户端和服务器不能一起工作!为什么?
您可能正在看到跨源资源共享(CORS)问题。您可以通过检查您的浏览器控制台看到如下错误来验证此问题(至少在Chrome中):
如果是这种情况,您可以通过替换以下行来启用服务器中的CORS:
app = serve userAPI server
用这行代码:
app = simpleCors(服务用户API服务器)
您需要导入wai-cors:
import Network.Wai.Middleware.Cors
这里是您的服务器服务器进行以下更改:
{ - #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)
导入Network.Wai.Middleware.Co rs
将合格的Data.Text导入为T
main :: IO()
main = withStdoutLogger $ \aplogger - >
让settings = setPort 8080 $ setLogger aplogger defaultSettings
runSettings settings app
$ b app :: Application $ b $ app = simpleCors(serve userAPI server)
userAPI :: Proxy API - API用法:http:// localhost:8080 / name / 2
userAPI =代理
类型API =name:>捕获pidInt:> 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 !!
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?
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:
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!!"
这篇关于使用反射客户端访问服务器服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!