如果我将基本路径附加到settings.yml中的approot属性,例如
approot="http://localhost:3000/base"
在浏览器中调用此 URL 会显示“未找到”作为消息,而不是正确提供主页。
我找不到任何方法来解决它。
...
我明白了,在将 URL 提交到 yesod 任务之前,我必须重写没有基本前缀的 URL,并且 approot 仅用于添加到所有页面链接的前面。
是否有适当的方法来处理这些基于非空路径的 URL?
如果我将基本路径附加到settings.yml中的approot属性,例如
approot="http://localhost:3000/base"
在浏览器中调用此 URL 会显示“未找到”作为消息,而不是正确提供主页。
我找不到任何方法来解决它。
...
我明白了,在将 URL 提交到 yesod 任务之前,我必须重写没有基本前缀的 URL,并且 approot 仅用于添加到所有页面链接的前面。
是否有适当的方法来处理这些基于非空路径的 URL?
有两种相对简单的方法:
通常,带有前导路径片段的 approot 在有一些前端服务器正在调用您的 Yesod 应用程序(通过反向代理或 FastCGI)时最有用。
按照 M.Snoyman 的提示,这里是一个解决问题的cleanPath版本,仅针对 ApprootMaster 构造函数的 approot 案例,由 生成yesod init
,作为生成的模块 Foundation.hs 的补充:
{-# LANGUAGE PackageImports #-}
import qualified Data.Text as Txt
import qualified "url" Network.URL as Url
import qualified Network.HTTP.Types as H
import qualified Data.Text.Encoding as TE
import qualified Data.List as L
import qualified "utf8-string" Data.ByteString.UTF8 as UTF8BS
-- instance Yesod App where
-- cleanPath - A function used to clean up path segments.
-- It returns Right with a clean path or Left with a new set of pieces the user should be redirected to
-- cleanPath :: Yesod a => a -> [Text] -> Either [Text] [Text]
cleanPath master s =
if corrected == s'
then Right $ cutoffBasePrefix s'
else Left $ cutoffBasePrefix corrected -- to be redirected
where
-- avoid redirection on slash ended urls by junking the last piece if it's null
s' = if not (L.null s) && Txt.null (last s) then init s else s
corrected = filter (not . Txt.null) s'
-- strToUtf8BS = TE.encodeUtf8 . Txt.pack -- packs to UTF16 then encodes to UTF8
strToUtf8BS = UTF8BS.fromString
-- cut off "base prefix" or leave as it is
cutoffBasePrefix segmts =
case approot of
ApprootMaster f ->
case Url.importURL $ Txt.unpack $ f master of
Nothing -> segmts -- not expected, incorrect url in settings.yml approot
Just url -> let basePrefixSegmts = H.decodePathSegments $ strToUtf8BS $ Url.url_path url in
case basePrefixSegmts of
[] -> segmts
_ -> if basePrefixSegmts `L.isPrefixOf` segmts
then drop (length basePrefixSegmts) segmts
else segmts
_ -> segmts
使用这些额外的包依赖项:
, url >= 2.1.2
, network
, http-types
, utf8-string