简体   繁体   English

使用reflex-dom客户端访问服务器服务器

[英]Acess a servant server with a reflex-dom client

I'm using version 0.4 of reflex-dom and I have a tiny 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"

As described in XhrRequest with reflex/reflex-dom , I'm using _xhrResponse_responseText and not decodeXhrResponse . XhrRequest with reflex / reflex-dom中所述 ,我使用_xhrResponse_responseText而不是decodeXhrResponse

When I run this client with the NASA URL, it displays a nice JSON string. 当我使用NASA URL运行此客户端时,它会显示一个不错的JSON字符串。 Therefore I assume, this reflex-dom client is working. 因此,我认为,这个反射dom客户端正在工作。

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 . 当我在浏览器中使用http://localhost:8080/name/3curl访问此服务器时,我看到了预期的结果Marie Curie Therefore I assume, this servant server is working. 因此我假设,这个servant服务器正在工作。

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 . 当我运行与本地主机的URL上面反射-DOM客户端,我可以看到服务器的标准输出日志的要求,但客户端显示居里夫人的名字。 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. 您可能正在看到跨源资源共享(CORS)问题。 You can verify this (in chrome at least) by checking your browser console for an error that looks like this: 您可以通过检查浏览器控制台查看如下错误来验证此信息(至少在chrome中):

XMLHttpRequest cannot load http://localhost:8080/name/3 . XMLHttpRequest无法加载http:// localhost:8080 / name / 3 No 'Access-Control-Allow-Origin' header is present on the requested resource. 请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin ' http://localhost:8000 ' is therefore not allowed access. 因此不允许来源' http:// localhost:8000 '访问。

If this is the case, you can enable CORS in your server by replacing this line : 如果是这种情况,您可以通过替换此行来启用服务器中的CORS:

app = serve userAPI server

with this line: 用这一行:

app = simpleCors (serve userAPI server)

You will need to import wai-cors: 你需要导入wai-cors:

import Network.Wai.Middleware.Cors

here is your servant server with these changes: 这是您的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!!"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM