Haskell http响应结果不可读

wen*_*ong 5 encoding haskell http

import Network.URI
import Network.HTTP
import Network.Browser

get :: URI -> IO String
get uri = do
  let req = Request uri GET [] ""
  resp <- browse $ do
    setAllowRedirects True -- handle HTTP redirects
    request req
  return $ rspBody $ snd resp

main = do
  case parseURI "http://cn.bing.com/search?q=hello" of
    Nothing -> putStrLn "Invalid search"
    Just uri -> do
        body <- get uri
        writeFile "output.txt" body
Run Code Online (Sandbox Code Playgroud)

这是haskell输出和curl输出之间的差异

vimdiff同时

ham*_*mar 8

String在这里使用中间数据类型可能不是一个好主意,因为它在读取HTTP响应和写入文件时都会导致字符转换.如果这些转换不一致,这可能会导致损坏,因为它们看起来就像在这里一样.

由于您只想直接复制字节,因此最好使用a ByteString.我选择在ByteString这里使用懒惰,因此它不必一次加载到内存中,但可以懒惰地流入文件,就像使用String.

import Network.URI
import Network.HTTP
import Network.Browser
import qualified Data.ByteString.Lazy as L

get :: URI -> IO L.ByteString
get uri = do
  let req = Request uri GET [] L.empty
  resp <- browse $ do
    setAllowRedirects True -- handle HTTP redirects
    request req
  return $ rspBody $ snd resp

main = do
  case parseURI "http://cn.bing.com/search?q=hello" of
    Nothing -> putStrLn "Invalid search"
    Just uri -> do
        body <- get uri
        L.writeFile "output.txt" body
Run Code Online (Sandbox Code Playgroud)

幸运的是,函数in Network.Browser被重载,因此对lazy bytestrings的更改只涉及将请求体更改为L.empty,替换writeFileL.writeFile,以及更改函数的类型签名.