В ELM запрос GET не может иметь тела, или нет?

Http.request, кажется, игнорирует body, когда метод GET

init : () -> ( Model, Cmd Msg )
init _ =
    ( Loading
    , Http.request
        { method = "GET"
        , headers = []
        , url = "http://127.0.0.1"
        , body = Http.stringBody "text/plain" "Hello World!"
        , expect = Http.expectWhatever Sent
        , timeout = Nothing
        , tracker = Nothing
        }
    )

Отправленный запрос не имеет тела (при проверке с помощью средства разработки браузера). 🤔

init : () -> ( Model, Cmd Msg )
init _ =
    ( Loading
    , Http.request
        { method = "POST" {- CHANGED TO POST -}
        , headers = []
        , url = "http://127.0.0.1"
        , body = Http.stringBody "text/plain" "Hello World!"
        , expect = Http.expectWhatever Sent
        , timeout = Nothing
        , tracker = Nothing
        }
    )

Но когда метод меняется на "POST", он работает! Тело содержит "Hello World!". 🤨

API, с которым я пытаюсь связаться, требует application/json тела в GET запросе. Помогите мне 😭 !

PS: Вот что написано в документации:

emptyBody : Body

Создайте пустое тело для вашего запроса. Это полезно для запросов GET и POST-запросы, в которых вы не отправляете никаких данных.

Что непонятно, потому что это можно интерпретировать двумя разными способами:

Это полезно для запросов GET и {запросов POST, в которых вы не отправляете никаких данных}.

Или:

Это полезно для {GET-запросов и POST-запросов}, когда вы не отправляете никаких данных.

Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
2
0
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Согласно спецификации HTTP, GET не должен иметь тела. См., например, его описание на MDN, в котором говорится:

Примечание. Отправка тела/полезной нагрузки в запросе GET может привести к тому, что некоторые существующие реализации для отклонения запроса — пока это не запрещено спецификация, семантика не определена. Лучше просто избегать отправка полезной нагрузки в GET запросах.

Ответ принят как подходящий

Elm действительно добавляет тело к запросу, но браузер его не отправляет.

Чтобы увидеть это, скомпилируйте эту программу Elm:

module Main exposing (main)

import Platform
import Http

main =
    Platform.worker
        { init = \() -> ((), Http.request
            { method = "GET"
            , headers = []
            , url = "https://catfact.ninja/fact"
            , body = Http.stringBody "text/plain" "hi"
            , expect = Http.expectWhatever (\_ -> ())
            , timeout = Nothing
            , tracker = Nothing
            })
        , update = \() () -> ((), Cmd.none)
        , subscriptions = \() -> Sub.none
        }

без флагов оптимизации, чтобы получить файл index.html. Часть этого файла:

        var xhr = new XMLHttpRequest();
        xhr.addEventListener('error', function() { done($elm$http$Http$NetworkError_); });
        xhr.addEventListener('timeout', function() { done($elm$http$Http$Timeout_); });
        xhr.addEventListener('load', function() { done(_Http_toResponse(request.expect.b, xhr)); });
        $elm$core$Maybe$isJust(request.tracker) && _Http_track(router, xhr, request.tracker.a);

        try {
            xhr.open(request.method, request.url, true);
        } catch (e) {
            return done($elm$http$Http$BadUrl_(request.url));
        }

        _Http_configureRequest(xhr, request);

        request.body.a && xhr.setRequestHeader('Content-Type', request.body.a);
        xhr.send(request.body.b);

Если вы откроете этот файл в браузере и пройдетесь по этой его части в отладчике, вы увидите, что Elm действительно помещает данное тело «привет» в значение request.body.b, переданное xhr.send.

Но если вы затем посмотрите на вкладку «Сеть» в консоли браузера, вы увидите, что запрос не содержит тела.

Так что это браузер удаляет тело с помощью GET-запросов, а не Elm.

Другие вопросы по теме