如何在Elm中读取cookie?

问题描述 投票:0回答:2

我在这个SO问题中了解到,目前没有简单的方法可以将基于cookie的CSRF令牌转换为Elm中的HTTP请求标头。因此,要编写一个与 Django Rest Framework 后端完美配合的单页应用程序 (SPA),我需要从相应的 cookie 值中手动检索 CSRF-Token。

如何在 Elm 中检索 cookie 值? Elm 是否通过某些命令为此提供运行时支持?或者我是否需要使用纯 JavaScript 检索 cookie 并通过端口将其提供给 ELM SPA?

cookies elm elm-port
2个回答
4
投票

从 Elm 0.9 开始,您需要使用 Ports 从 JavaScript 读取 cookie 并将其传回 Elm 应用程序。

在我的申请中,我执行以下操作。我定义了一个

fetchCsrfToken
端口,使用 Elm 来调用读取 cookie 的 JavaScript 函数。然后该函数通过
csrfTokenReceiver
端口触发对 Elm 的回调。我的 Elm 应用程序通过订阅来订阅该事件。

-- Ports.elm

port fetchCsrfToken : () -> Cmd msg
port csrfTokenReceiver : (String -> msg) -> Sub msg
-- Main.elm

init : Flags -> Url -> Key -> ( Model, Cmd Msg )
init flags url key =
  -- ...
  (model, Ports.fetchCsrfToken ())
  

subscriptions : Model -> Sub Msg
subscriptions model =
  Ports.csrfTokenReceiver GotCsrfToken
// index.js

app.ports.fetchCsrfToken.subscribe(function (str) {
  const value = getCookie('csrftoken')
  if (value === null) {
    app.ports.csrfTokenReceiver.send('')
  } else {
    app.ports.csrfTokenReceiver.send(value)
  }
})

1
投票

使用Elm 0.19.1

第一个解决方案:

使用 2 个端口、订阅和一些 JS/TS 代码,如 @viam0Zah 提到的。


第二种解决方案:

在 init 时将 CSRF 传递到您的标志中

    const app = Elm.Main.init({
      node: document.querySelector("main"),
      flags: {
        csrfToken: getCookie('csrftoken')
      }
    });

将 csrfToken 添加到标志

type alias Flags =
    { ---
    , csrfToken : String
    }

不要忘记为 csrfToken 添加解码器:

import Json.Decode as D

flagsDecoder : D.Decoder Flags
flagsDecoder =
    D.succeed Flags
        |> ---
        |> D.required "csrfToken" D.string

如果您想更加健壮并扩展两种解决方案(标志和端口)的类型安全性,您应该查看 https://elm-ts-interop.com/,这太棒了!

© www.soinside.com 2019 - 2024. All rights reserved.