Elm http请求返回成功请求的NetworkError

Elm http请求返回成功请求的NetworkError,http,elm,Http,Elm,我有相当多的经验,建立网络应用与反应,但想学习Elm。几天来,我一直在为HTTP请求问题绞尽脑汁 我在localhost:8080上运行一个Elm应用程序,在localhost:8081上运行我的支持API。每当我发出HTTP请求(我尝试了GET和POST请求)时,就会收到一个NetworkError。我一直在研究Elm JSON解码器,认为这可能是我的问题所在,但我尝试从服务器发送简单字符串,并在我的Elm应用程序中使用Decode.string解码器,但我仍然收到NetworkError 以

我有相当多的经验,建立网络应用与反应,但想学习Elm。几天来,我一直在为HTTP请求问题绞尽脑汁

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

以下是我的代码当前的样子:

埃尔姆先生

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"
埃尔姆

module Models exposing (..)


type alias ApiResponse =
  { status: Int
  , message: String
  , created: Int
  , error: String
  }
榆树味精

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库没有完全的了解,但我的印象是,如果这就是问题所在,我会得到一个未预料到的负载错误,包括额外的上下文。

@Sidney和@SimonH

谢谢你帮我调查这件事,我感觉很糟糕,因为这毕竟不是榆树的问题

该解决方案最终使用服务器上的CORS中间件添加“Access Control Allow Origin”头。服务器仍以200状态响应,甚至包括整个成功响应主体,但这导致Elm的Http结果失败


再次感谢您的时间和想法

要在开发时快速解决问题,您可以使用For firefox,并在扩展首选项中将以下内容添加到您的白名单中:

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

对于chrome,您可能可以使用

因此,chrome开发工具显示您实际上得到了成功的响应,但Elm报告了NetworkError?你怎么知道你收到了NetworkError?在我的更新Msg.TempUserCreated(Err-Err)中,我将错误字符串保存到我的模型中,并在应用程序视图中显示我的模型,以便我可以看到模型在我提出请求时更新为model.error=“NetworkError”,我自己加载了repo。由于我没有在
:8081
上运行API服务器,所以正如您所期望的那样,每个请求都失败了。但我从未在模型中实际看到
网络错误!模型中的错误始终为空。我添加了一个
Debug.log
,果然得到了一个
NetworkError
。如果没有API服务器,我可能无法重新创建错误。我看到您在某个json对象中返回200,但http头本身是否得到200?@SimonH问得好,可能服务器实际发送了不同的状态。虽然从理论上讲,非成功状态应该导致
BadStatus
错误,而不是
NetworkError
很好,您共享了完整的代码,但对于像我这样正在学习Elm的人来说,查看任何代码都很有用;)这有点像Elm问题,因为错误的原因,即缺少CORS头,在Elm代码内部发出的请求和Elm代码接收到的NetworkError之间的某个地方被吞没或丢失。如果是您自己的答案,请接受。这对有相同问题的人很有用。