首页 > 解决方案 > 如何正确制定wai queryString?

问题描述

我正在尝试制定代码,这将允许我在 html 输入字段中打印一些内容,然后 Haskell 代码将返回我在下一个 div 中打印的内容(从长远来看,这是一个 Ajax 搜索引擎)。两者之间的联系似乎已经建立,但以一种非常奇怪的方式。不仅如此,我不太明白如何按以下顺序为 queryString req 制作案例。这是 Haskell 代码:

{-# LANGUAGE OverloadedStrings #-}

import Network.Wai
import Network.Wai.Handler.Warp
import Network.HTTP.Types
import Data.ByteString.Lazy

main :: IO ()
main = run 3000 app

app :: Application
app req resp = do
  case pathInfo req of
    ["main"] -> resp $ responseFile status200 [("Content-Type","text/html")] "search.html" Nothing
    _ -> resp $ responseLBS status404 [("Content-Type","text/plain")] "No such file."
  case queryString req of
    [("q=",Just stuff)] -> resp $ responseLBS
      status200
      [("Content-Type","text/html")]
      (fromStrict stuff)
    [("q=",Just "")] -> resp $ responseLBS
      status200
      [("Content-Type","text/html")]
      ""
    _ -> resp $ responseLBS
      status404
      [("Content-Type","text/html")]
      "sorry"

这是我的搜索页面:

<!DOCTYPE html>
<html>
  <script>
  function getStuff(str) {
    if (str.length == 0) {
      document.getElementById("results").innerHTML = "";
      return;
    } else {
      var xmlhttp = new XMLHttpRequest();
      xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          document.getElementById("results").innerHTML = this.responseText;
        }
      };
      xmlhttp.open("GET", "http://localhost:3000/main?q=" + str, true);
      xmlhttp.send();
    }
  }
  </script>
  <body>
    <input type = "text" onkeyup = "getStuff(this.value)"/>
    <p><span id = "results"></span></p>
  </body>
</html>

标签: ajaxhaskellhaskell-warp

解决方案


免责声明:我没有尝试编译此代码。我没有使用 WAI/Warp 的经验。这只是尝试看看它是否有效!

app req resp = do
  case (pathInfo req, queryString req) of
    (["main"], [("q", Just stuff)]) ->
      resp $ responseLBS  status200 [("Content-Type","text/html")]  (fromStrict stuff)
    (["main"], _) ->
      resp $ responseFile status200 [("Content-Type","text/html")]  "search.html" Nothing
    _ ->
      resp $ responseLBS  status404 [("Content-Type","text/plain")] "No such file."

为了使它成为一个更普遍有用的答案(如果它确实解决了问题):在您的原始代码中,您有两个case将连续执行的块,以及每个块调用的所有分支resp,因此您保证调用resp两次,我认为,它会为每个请求产生(或尝试产生)两个响应。一般来说,这在 HTTP 中不会发生,因此您可能只会得到第一个响应,而这恰好根本不使用查询字符串。修复只是为了确保您只调用resp一次,在您检查了您需要检查您的请求的所有内容之后!我向您展示了一种方法,即同时匹配路径和查询字符串,但当然还有其他方法。你可以匹配pathInfo req首先,然后queryString req在其中一些相关的情况下进行匹配。只要确保resp每个可能的代码路径只被调用一次。


推荐阅读