Я начал с Elm и хочу получить изображения из Trefle API при поиске растения, но продолжаю получать ошибку «Не удалось получить изображение». Я использую свой собственный токен доступа, но здесь я заменил его на «MY_API_TOKEN», чтобы сохранить его конфиденциальность. Можете ли вы помочь мне понять проблему в моем коде?
Я пытался получить более подробное сообщение об ошибке, но мой код дал сбой, потому что я новичок в использовании elm и в области веб-разработки.
module Main exposing (..)
import Browser
import Html exposing (Html, button, div, img, input, text)
import Html.Attributes exposing (placeholder, src, type_)
import Html.Events exposing (onClick, onInput)
import Http
import Json.Decode exposing (Decoder, field, list, string)
import Maybe exposing (withDefault, map)
type alias Model =
{ searchTerm : String
, imageUrl : String
, error : String
}
init : () -> ( Model, Cmd Msg )
init _ =
( { searchTerm = "", imageUrl = "", error = "" }, Cmd.none )
type Msg
= UpdateSearchTerm String
| FetchImage
| ReceiveImage (Result Http.Error String)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
UpdateSearchTerm term ->
( { model | searchTerm = term }, Cmd.none )
FetchImage ->
( model, fetchPlantImage model.searchTerm )
ReceiveImage result ->
case result of
Ok url ->
( { model | imageUrl = url, error = "" }, Cmd.none )
Err _ ->
( { model | error = "Failed to fetch image." }, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ input [ placeholder "Enter plant name", onInput UpdateSearchTerm ] []
, button [ onClick FetchImage ] [ text "Search" ]
, if model.imageUrl /= "" then
img [ src model.imageUrl ] []
else
text ""
, if model.error /= "" then
div [] [ text model.error ]
else
text ""
]
fetchPlantImage : String -> Cmd Msg
fetchPlantImage searchTerm =
let
url =
"https://trefle.io/api/v1/plants/search?token=MY_API_TOKEN&q = " ++ searchTerm
decodeImageUrl : Decoder String
decodeImageUrl =
field "data" (list (field "image_url" string))
|> Json.Decode.map (withDefault "" << map identity << List.head)
in
Http.get
{ url = url
, expect = Http.expectJson ReceiveImage decodeImageUrl
}
main : Program () Model Msg
main =
Browser.element
{ init = init
, update = update
, subscriptions = \_ -> Sub.none
, view = view
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже, срок действия SSL-сертификата trefle.io истек, поэтому, скорее всего, проблема на их стороне.
Первое, что я сделал, это обновил обработчик HTTP-ответа, чтобы он был более явным при сообщении об ошибке (а не просто «Не удалось получить изображение»).
...
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
...
ReceiveImage result ->
case result of
Ok url ->
( { model | imageUrl = url, error = "" }, Cmd.none )
Err err ->
( { model
| error =
case err of
Http.BadUrl errorMessage ->
errorMessage
Http.Timeout ->
"Timeout"
Http.NetworkError ->
"Network error"
Http.BadStatus status ->
"Bad status " ++ String.fromInt status
Http.BadBody errorMessage ->
errorMessage
}
, Cmd.none
)
...
Элли: https://ellie-app.com/rqZy7NHmGrGa1
Как только вы это сделаете, вы увидите, что фактическая ошибка:
Ошибка сети
Подразумевается, что сервис недоступен.
Затем я просто попытался получить доступ к этому URL-адресу с помощью curl, который сообщает об ошибке SSL-сертификата сервера:
% curl "https://trefle.io/api/v1/plants/search?token=MY_API_TOKEN&q=coconut"
curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
HTTPS-proxy has similar options --proxy-cacert and --proxy-insecure.
Похоже, срок действия сертификата истек 4 дня назад. Надеюсь, они скоро решат эту проблему.
как и "сегодня" - до сих пор не исправлено.
Можете ли вы опубликовать точное сообщение об ошибке?