我正在尝试创建使用AJAX与服务器通信的简单页面(Yesod).到目前为止,我设法从服务器传递数据,但我不知道如何使用服务器处理程序(putJsonpR)获取客户端数据.
这是我到目前为止:
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Yesod
import Database.PostgreSQL.Simple
import Database.PostgreSQL.Simple.FromRow
import Database.PostgreSQL.Simple.ToRow
import Database.PostgreSQL.Simple.ToField
import Data.Aeson
import Data.Text (Text)
import Control.Applicative
import Control.Monad
import GHC.Generics
data HelloWorld = HelloWorld
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
/json/#Int JsonR GET
/json JsonpR PUT
|]
instance Yesod HelloWorld
data Person = Person {
personId :: Int,
name :: String,
age :: Int
} deriving (Show,Generic)
instance FromJSON Person
instance ToJSON Person
instance FromRow Person where
fromRow = Person <$> field <*> field <*> field
instance ToRow Person where
toRow d = [ toField (personId d), toField (name d), toField (age d)]
getConnectionString = do
cnn <- connect defaultConnectInfo {
connectHost = "127.0.0.1"
, connectPort = 5432
, connectUser = "postgres"
, connectPassword = "123456"
, connectDatabase = "tst"
}
return (cnn)
getPerson id = do
cnn <- getConnectionString
xs <- query cnn "select \"PersonId\", \"Name\", \"Age\" from \"Person\" where \"PersonId\" = ?" (Only (id :: Int)) :: IO [Person]
return (head xs)
getHomeR :: Handler ()
getHomeR = sendFile typeHtml "staticpage.html"
getJsonR :: Int -> Handler Value
getJsonR personId = do
person <- liftIO $ getPerson personId
returnJson $ person
putJsonpR :: Handler Value
putJsonpR = do
person <- parseJsonBody_ :: Handler Person
returnJson $ person
main :: IO ()
main = warp 3000 HelloWorld
Run Code Online (Sandbox Code Playgroud)
这是HTML页面:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript">
function getPerson () {
$.ajax({
url: "/json/" + 1,
success: function (data) {
alert (data.personId + " - " + data.name + " - " + data.age);
},
dataType: "json"
});
}
function save() {
$.ajax({
url: "/json",
type: "PUT",
data: { "personId": 123, "name": "from gui", "age": 123 },
success: function (data) {
alert (data.personId + " - " + data.name + " - " + data.age);
},
error: function(xhr, status, error) {
alert(xhr.responseText);
},
dataType: "json"
});
}
</script>
</head>
<body>
<input type="button" onclick="getPerson()" value="get" />
<br />
<br />
<br />
<input type="button" onclick="save()" value="put" />
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我收到了AJAX错误消息:"读取失败:不是有效的json值"
另外,有没有办法输出我从AJAX请求得到的任何东西?
就像是:
putSomethingR = do
liftIO $ print $ whateverCameFromAjax
-- rest of handler
Run Code Online (Sandbox Code Playgroud)
我在FP Haskell Center上汇总了这样做的样本.代码也包含在下面.
您最初编写的内容存在于Javascript代码中.你的jQuery参数告诉它创建一个URL编码的请求体.您需要手动将JSON呈现为文本,然后关闭处理processData: false.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Yesod
import Yesod.Form.Jquery (YesodJquery (urlJqueryJs))
import Data.Conduit
import qualified Data.Conduit.Text as CT
import qualified Data.Conduit.List as CL
import qualified Data.Text as T
data App = App
mkYesod "App" [parseRoutes|
/ HomeR GET
/echo-body EchoBodyR PUT
|]
instance Yesod App
instance YesodJquery App
getHomeR :: Handler Html
getHomeR = defaultLayout $ do
setTitle "Yesod + Ajax"
getYesod >>= addScriptEither . urlJqueryJs
[whamlet|
<button #echo>Echo body
|]
toWidget script
script = [julius|
$(function(){
$("#echo").click(function(){
$.ajax({
// sending a JSON encoded body
contentType: "application/json",
// don't process the body, we'll render data into a valid string
processData: false,
url: "@{EchoBodyR}",
type: "PUT",
// notice the usage of stringify here
data: JSON.stringify([{name:"Alice",age:25}, {name:"Bob",age:30}]),
success: function(data) {
alert(data.body);
},
// this only refers to the data type of the *returned* data
dataType: "json"
});
});
});
|]
putEchoBodyR :: Handler Value
putEchoBodyR = do
texts <- rawRequestBody $$ CT.decode CT.utf8 =$ CL.consume
return $ object ["body" .= T.concat texts]
main :: IO ()
main = warpEnv App
Run Code Online (Sandbox Code Playgroud)
在“GET”方面,由于您不使用持久模板,而是使用 Database.PostgreSQL.Simple.query 中的数据库级 sql,使用真实的数据库标识符解决了错误。
getPerson id = do
cnn <- getConnectionString
xs <- query cnn "select \"id\", \"name\", \"age\" from \"person\" where \"id\" = ?" (Only (id :: Int)) :: IO [Person]
return (head xs)
Run Code Online (Sandbox Code Playgroud)
在“PUT”方面,您的 staticpage.html jquery 脚本上存在 ajax 解析错误,当您将“data”字段括在单引号中时已更正:
function save() {
$.ajax({
url: "/json",
type: "PUT",
data: '{ "personId": 123, "name": "from gui", "age": 123 }',
...
dataType: "json"
...
Run Code Online (Sandbox Code Playgroud)
第三。您可以使用以下命令记录ajax 输出
$(logDebug) (show whatEverCameFromAjax)
Run Code Online (Sandbox Code Playgroud)
如果您使用 yesod 脚手架,则来自 MonadLogger 实例 monad。
| 归档时间: |
|
| 查看次数: |
1228 次 |
| 最近记录: |