Elm http请求返回NetworkError以获取成功请求

时间:2018-02-16 00:30:24

标签: http elm

我有很多使用React构建Web应用程序的经验,但想学习Elm。我已经在几天内针对HTTP请求问题敲打头了。

我在localhost:8080运行Elm应用程序,在localhost:8081运行我的支持API。每当我发出HTTP请求(我已尝试过GET和POST请求)时,我都会收到NetworkError。我一直在研究Elm JSON解码器,并认为这可能是我的问题存在但我尝试从我的服务器发送简单字符串并在我的Elm应用程序中使用Decode.string解码器我仍然得到NetworkError。

这是我目前的代码:

Commands.elm

module Commands exposing (..)

import Models exposing (..)
import Msg exposing (..)
import Http
import Json.Decode as Decode
import Json.Encode as Encode


createTempUser : Model -> Cmd Msg
createTempUser model =
  let
    tempUserBody =
      [ ( "firstname", Encode.string model.firstname )
      , ( "lastname", Encode.string model.lastname )
      , ( "phone", Encode.string model.phone )
      ]
        |> Encode.object
        |> Http.jsonBody

    url =
      myAPIUrl ++ "/endpoint"

    contentType = Http.header "Content-type" "text/plain"

    post =
      Http.request
        { method = "POST"
        , headers =  [contentType]
        , url = url
        , body = tempUserBody
        , expect = Http.expectJson decodeApiResponse
        , timeout = Nothing
        , withCredentials = False
        }

  in
    Http.send Msg.TempUserCreated post


decodeApiResponse : Decode.Decoder ApiResponse
decodeApiResponse =
  Decode.map4 ApiResponse
    (Decode.at ["status"] Decode.int)
    (Decode.at ["message"] Decode.string)
    (Decode.at ["created"] Decode.int)
    (Decode.at ["error"] Decode.string)


myAPIUrl : String
myAPIUrl = "http://localhost:8081"

Models.elm

module Models exposing (..)


type alias ApiResponse =
  { status: Int
  , message: String
  , created: Int
  , error: String
  }

Msg.elm

module Msg exposing (..)

import Navigation exposing (Location)
import Models exposing (..)
import Http


type Msg
  = ChangeLocation String
  | OnLocationChange Location
  | CreateTemporaryUser
  | TempUserCreated ( Result Http.Error ApiResponse )

Update.elm

module Update exposing (..)

import Msg exposing (Msg)
import Models exposing (..)
import Routing exposing (..)
import Commands exposing (..)
import Navigation

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Msg.ChangeLocation path ->
      ( { model | changes = model.changes + 1 }, Navigation.newUrl path )

    Msg.OnLocationChange location ->
      ( { model | error = "", route = parseLocation(location) }, Cmd.none )

    Msg.CreateTemporaryUser ->
      ( model, createTempUser model )

    Msg.TempUserCreated (Ok res) ->
       update (Msg.ChangeLocation signupCodePath) { model | httpResponse = toString(res) }

    Msg.TempUserCreated (Err err) ->
      ( { model | error = toString(err) }, Cmd.none )

Chrome的网络开发工具以

显示响应
{"status":200,"message":"Successfully inserted temporary 
user","created":1518739596447,"error":""}

我认为这可能是所有相关的代码,但如果还有更多,您需要查看我将进行更新,包括所请求的代码。我承认我没有完全了解Elm Json.Decode库,但我的印象是,如果这是问题所在,我会得到一个包含额外上下文的UnexpectedPayload错误。 / p>

2 个答案:

答案 0 :(得分:6)

@Sidney和@SimonH,

感谢您为我调查,我感觉很糟糕,因为这毕竟不是榆树问题。

解决方案最终使用服务器上的CORS中间件来添加“访问控制 - 允许 - 来源”#39;头。服务器仍然以200状态响应,甚至包括整个成功的响应机构,但这导致了Elm的Http结果失败。

再次感谢您的时间和思想!

答案 1 :(得分:1)

对于开发时的快速解决方案,您可以将CORS everywhere extension用于Firefox,并在扩展程序首选项中将以下内容添加到白名单中:

/^https?...localhost:8888\//i

对于Chrome,您可能可以使用this extension