使用反射客户端访问服务器服务器 [英] Acess a servant server with a reflex-dom client

查看:451
本文介绍了使用反射客户端访问服务器服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是反射式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

如上所述在 XrefRequest与reflex / reflex-dom 中,我正在使用 _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中):


XMLHttpRequest无法加载 http:// localhost:8080 / name / 3
'Access-Control-Allow-Origin'标题存在于请求的
资源中。原因' http:// localhost:8000 '因此是不允许的
访问。


如果是这种情况,您可以通过替换以下行来启用服务器中的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:

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!!"

这篇关于使用反射客户端访问服务器服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆