Elm发送Get请求报NetworkError,但浏览器控制台显示请求正常
Hey there! That mismatch between your browser showing a successful request and Elm throwing a NetworkError is a super common gotcha—Elm's Http module is pickier about what counts as a "valid" response than the browser is. Let's break down the most likely fixes:
1. You're returning plain text without setting the right Content-Type
Elm's default Http.get expects JSON by default, but your Scotty server is just sending back the letter 'a' with no explicit content type header. Even though the browser sees a 200 OK, Elm doesn't know how to handle a response that isn't marked as a type it understands, so it throws a NetworkError.
Fix your Scotty server first:
Add a Content-Type header to tell the client this is plain text:
import Network.HTTP.Types.Header (hContentType) get "/" $ do addHeader hContentType "text/plain" text "a"
Then update your Elm code to expect a string instead of JSON:
import Http -- Updated request to handle plain text responses fetchA : Cmd Msg fetchA = Http.get { url = "http://localhost:3000" , expect = Http.expectString GotResponse } -- Update your Msg and update logic to handle the string result type Msg = FetchA | GotResponse (Result Http.Error String) update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of FetchA -> ( model, fetchA ) GotResponse result -> case result of Ok response -> ( { model | content = response }, Cmd.none ) Err err -> ( { model | error = Just (Http.errorToString err) }, Cmd.none )
2. Missing CORS configuration
Even if the request looks successful in the browser, Elm might block it due to CORS rules. Local servers often forget to set the right CORS headers, which triggers this error in Elm even if the browser shows a 200.
Add CORS support to Scotty:
You can either use the scotty-cors package or manually add the headers. Here's the manual approach:
import Network.HTTP.Types.Header import Network.HTTP.Types.Status (status200) -- Add CORS headers to all responses middleware $ addHeaders [ (hAccessControlAllowOrigin, "*") , (hAccessControlAllowMethods, "GET, POST, OPTIONS") , (hAccessControlAllowHeaders, "Content-Type") ] -- Handle OPTIONS preflight requests (required for proper CORS support) options "/" $ do addHeader hAccessControlAllowOrigin "*" addHeader hAccessControlAllowMethods "GET, POST, OPTIONS" addHeader hAccessControlAllowHeaders "Content-Type" status status200
This tells Elm's Http module that it's allowed to make requests to your local server.
Quick validation steps
- Restart your Scotty server to apply the changes
- Open your browser's DevTools > Network tab, and check:
- The
Content-Typeheader in the response matches what you set (text/plain) - You see
Access-Control-Allow-Originand other CORS headers if you needed them
- The
- Click the button in your Elm app again—this should now pull in the 'a' without errors.
If you're still stuck, double-check that your Elm app is using the exact URL (including http:// and port 3000) and that your Scotty server is actually listening on port 3000. You could also add logging in Scotty to confirm that the request is hitting the server at all.
内容的提问来源于stack exchange,提问作者8n8

