Как правильно сформулировать wai queryString? - PullRequest
0 голосов
/ 01 мая 2019

Я пытаюсь сформулировать код, который позволил бы мне напечатать что-то внутри поля ввода html, а затем код на Haskell вернет то, что я напечатал в следующем div (чтобы сделать поисковую систему Ajax в долгосрочной перспективе)).Связь между ними, кажется, установлена, но очень странным образом.Более того, я не совсем понимаю, как создавать аргументы для запроса queryString в следующей последовательности.Вот код 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>

1 Ответ

1 голос
/ 02 мая 2019

Отказ от ответственности: я не пытался скомпилировать этот код. У меня нет опыта работы с 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 вызывается только один раз для каждого возможного пути кода.

...