Elm http请求为成功请求返回NetworkError [英] Elm http request returns NetworkError for successful requests

查看:217
本文介绍了Elm http请求为成功请求返回NetworkError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有大量使用React构建Web应用程序的经验,但想学习Elm。几天来,我一直在努力应对HTTP请求问题。



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

这是我当前的代码:



Commands.elm

  module暴露命令(..)

import暴露模型(..)
import消息暴露(..)
导入Http
导入Json.Decode为解码
导入Json.Encode为编码


createTempUser:模型-> Cmd Msg
createTempUser模型=

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
,标头= [contentType]
,url = url
,body = tempUserBody
,期望= Http.expectJson encodeApiResponse
,超时= Nothing
,withCredentials = False
}

in
Http.send Msg。 TempUserCreated post


decodeApiResponse:Decode.Decoder ApiResponse
decodeApiResponse =
Decode.map4ApiResponse
(Decode.at [ status] Decode.int )
(Decode.at [ message] Decode.string)
(Decode.at [ created] Decode.int)
(Decode.at [ error]解码。字符串)


myAPIUrl:字符串
myAPIUrl = http:// localhost:8081

Models.elm

 模块暴露模型(..)


类型别名ApiResponse =
{状态:Int
,消息:字符串
,创建:Int
,错误:字符串
}

Msg.elm

  module消息暴露(..)

导入导航暴露(位置)
导入模型暴露(..)
导入Http


类型消息
= ChangeLocation字符串
| OnLocationChange位置
| CreateTemporaryUser
| TempUserCreated(结果Http.Error ApiResponse)

Update.elm

  module更新暴露(..)

导入Msg暴露(Msg)
导入模型暴露(..)
import路由暴露(..)
import命令暴露(..)
import导航

更新:Msg->型号-> (Model,Cmd Msg)
更新msg模型=
情况
Msg.ChangeLocation path的msg。
({model | changes = model.changes + 1},Navigation.newUrl path)

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

Msg.CreateTemporaryUser->
(model,createTempUser model)

Msg.TempUserCreated(确定)->
更新(Msg.ChangeLocation signupCodePath){模型| httpResponse = toString(res)}

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

Chrome浏览器网络devtools将响应显示为

  { status:200, message:已成功插入临时
user, created:1518739596447, error:}

我认为这可能是所有相关代码,但如果需要更多信息,我将进行更新,包括请求的代码。我承认我对Elm Json.Decode库没有完全的了解,但是我给人的印象是,如果这是问题所在,我会收到一个UnexpectedPayload错误,其中包括其他上下文。

解决方案

@Sidney和@SimonH,



感谢您帮我了解一下,我感到很难受,因为毕竟这不是Elm问题。



该解决方案最终在服务器上使用CORS中间件添加了 Access-Control-Allow-来源的标头。服务器仍以200状态响应,甚至包括整个成功的响应正文,但这导致Elm的Http结果失败。



再次感谢您的宝贵时间,想!


I have a fair amount of experience building web apps with React but want to learn Elm. I've been banging my head against an HTTP request issue for a couple days now.

I'm running an Elm app at localhost:8080 and my supporting API at localhost:8081. Whenever I make an HTTP request (I've tried both GET and POST requests) I get a NetworkError. I've been looking into Elm JSON decoders and think it's possible that this is where my problem exists but I've tried sending simple strings from my server and using the Decode.string decoder in my Elm app and I still get the NetworkError.

Here's what my code looks like currently:

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's Network devtools show the response as this

{"status":200,"message":"Successfully inserted temporary 
user","created":1518739596447,"error":""}

I think this may be all the relevant code but if there's more you need to see I'll make an update including the requested code. I'll admit that I don't have a full understanding of the Elm Json.Decode library but I was under the impression that if this was where the issue was I would get an UnexpectedPayload Error that included additional context.

解决方案

@Sidney and @SimonH,

Thank you for looking into this for me, I feel bad because this wasn't an Elm issue after all.

The solution ended up using a CORS middleware on the server to add the 'Access-Control-Allow-Origin' header. The server was still responding with a 200 status and even included the entire successful response body but this resulted in a failure in Elm's Http Result.

Thank you again for your time and thought!

这篇关于Elm http请求为成功请求返回NetworkError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆