window.fetch() requests that return 401 code do not get their data returned

Issue #14320968 • Assigned to Steven K.

Details

Author
Wojciech K.
Created
Oct 20, 2017
Privacy
This issue is public.
Found in
  • Microsoft Edge
Found in build #
16.16299
Reports
Reported by 1 person

Sign in to watch or report this issue.

Steps to reproduce

When trying to implement authentication in an application, I’ve come across the following - when using window.fetch to make an API call that results in 401 error, the response is not returned and an empty string is returned instead. For example:

window.fetch('/api/method', {
  method: 'POST', body: '{"data":"data"}'
}).then(function(r) {return r.json();})
.then(function(ok) {console.log('OK', ok);},
  function(e) {console.log('ERROR',err);});

If /api/method returns any other HTTP code (i.e. 200, 201, 404), then the result is returned and OK logs the json data. However, if the returned code is 401, .json() throws an error that it can’t parse the body.

All other browsers I’ve tested (Chrome 61, Firefox 56) do return the response properly and the issue only happens with Edge.

Ideally the authentication model for the application I am working on will depend on HTTP code being 401 and the response providing enough information to authenticate the user by the frontend and perform auth again.

This does not seem to be possible with Edge.

As 403 code is already used for other things, it can’t be switched to that code. Also 401, not 403 should be used to indicate the application has to provide Authorization HTTP header.

Attachments

0 attachments

    Comments and activity

    • Microsoft Edge Team

      Changed Assigned To to “Steven K.”

    • Do you have a working repro for this?  Client and server side?  A simplified repro would help get this sorted out as fast as possible.  Perhaps you are aware of a w3c test case for this scenario?  I took a quick look and did not find anything yet.  I will keep looking.

      Appreciate the help,

      Steve

    • Sure,

      Below is a sample code in Go that serves sample JSON data as /test/(code) and a sample HTML+JS page that demonstrates the issue.

      I can provide a compiled binary if this helps in any way, but this just uses vanilla Go packages so all you should need to build is to get the Go installer/zip file and run go build inside the directory where you put the code below as main.go. The example is also relatively trivial and is just about a server that returns all the codes.

      It logs results to console.

      On Chrome/Firefox, the output is more or less:

      Parsed JSON for 200 : {"sample":"data"}
      Parsed JSON for 201 : {"sample":"data"}
      GET http://192.168.5.6:8081/test/500 500 (Internal Server Error)
      Parsed JSON for 500 : {"sample":"data"}
      GET http://192.168.5.6:8081/test/404 404 (Not Found)
      Parsed JSON for 404 : {"sample":"data"}
      GET http://192.168.5.6:8081/test/403 403 (Forbidden)
      Parsed JSON for 403 : {"sample":"data"}
      GET http://192.168.5.6:8081/test/401 401 (Unauthorized)
      Parsed JSON for 401 : {"sample":"data"}
      All tests have finished
      

      For Edge it is:

       Parsed JSON for 200 : {"sample":"data"}
       Parsed JSON for 201 : {"sample":"data"}
       Parsed JSON for 500 : {"sample":"data"}
       HTTP500: SERVER ERROR - The server encountered an unexpected condition that prevented it from fulfilling the request.
      (Fetch)GET - http://127.0.0.1:8081/test/500
       Parsed JSON for 404 : {"sample":"data"}
       HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
       Parsed JSON for 403 : {"sample":"data"}
       HTTP403: FORBIDDEN - The server understood the request, but is refusing to fulfill it.
      (Fetch)GET - http://127.0.0.1:8081/test/403
      Error for 401 : SyntaxError: Failed to read.
       All tests have finished
      127.0.0.1:8081 (33,25)
       HTTP401: DENIED - The requested resource requires user authentication.
      (Fetch)GET - http://127.0.0.1:8081/test/401
      

      The error SyntaxError: Failed to read. is because the response is not fetched and so parsing fails.

      If you replace return r.json() with return r.text() and replace JSON.stringify(r)) with r) (so change it to fetch and log the actual text returned), it will log empty response for 401 and proper JSON returned by the server for any other code.

      package main
      
      import (
          "fmt"
          "net/http"
          "strconv"
          "strings"
      )
      
      var (
          json = `{"sample": "data"}`
      )
      
      // return a JSON data (see above) along with proper exit code
      // this is set up to serve as  /test/(code)
      // i.e. /test/401, /test/200 and return requested code
      func returnJSON(w http.ResponseWriter, r *http.Request) {
          splitURL := strings.Split(r.RequestURI, "/")
          code, err := strconv.Atoi(splitURL[len(splitURL)-1])
          // if parsing the code from
          if err != nil {
              http.Error(w, fmt.Sprintf("%q", err), 500)
              return
          }
      
          w.Header().Set("Content-Type", "application/json")
          w.WriteHeader(code)
          fmt.Fprintf(w, "%s", json)
      }
      
      // return HTML with the script that demonstrates the issue
      func returnPage(w http.ResponseWriter, r *http.Request) {
          fmt.Fprintln(w, `
              
                  
                      
                      
                      
                      
                  
      
              
                  
                      Please open console window
                  
      
              
      
          `)
      }
      
      func main() {
          http.HandleFunc("/", returnPage)
          http.HandleFunc("/test/", returnJSON)
          http.ListenAndServe(":8081", nil)
      }
      
    • Hello, is there any update on this?

      I would want to understand if this is something where Edge will be consistent with other browsers (even if this will take time to be delivered to all users of the browser) or not.

      The site I’m working on is affected and knowing if fixing it would be temporary solution or if we need to look for a permanent one would help us in deciding.

    You need to sign in to your Microsoft account to add a comment.

    Sign in