title: Accessing document.cookie returns empty string even though cookies are listed in developer tools with httpOnly flag set to false
body: <p>Sometimes*, when accessing <code>document.cookie</code> in the login page I get an empty string even though: </p>
  
  <ol>
  <li>cookies are listed in the Chrome and Firefox developer tools,</li>
  <li>httpOnly flag of cookie I'm interested in is set to false,</li>
  <li>path of cookie I'm interested in is set to '/'. </li>
  </ol>
  
  <p><strong>Desired behaviour</strong></p>
  
  <p>My React single page application (SPA) has a login page which contains a <code>&lt;form /&gt;</code> element for sending login credentials to the backend. When the response from the backend is received and the authentication was successful, I check whether the authentication cookie has been set, properly. If that's the case a redirect will be triggered that shows the content for logged in users. </p>
  
  <p><strong>Actual behaviour</strong></p>
  
  <p>Unfortunately, in like <strong>15%</strong> of the login attempts, <code>document.cookie</code> returns an empty string which prevents the redirection and keeps the user on the login page. Pressing <code>F5</code> doesn't do the trick but when manually replacing a path of the url after a successful login request (e.g. updating 'www.website.tld/<strong>login</strong>' to 'www.website.tld/<strong>start</strong>') the user gets forwarded to the desired page which is for logged in users, only.</p>
  
  <p>I'm not able to reproduce the error manually. It just seems to happen randomly. But when it occurs and I have a look into the developer console I can see all the cookies from the backend (set correctly).</p>
  
  <p><strong>Additional information</strong></p>
  
  <ul>
  <li>a django server is running in the backend </li>
  <li>the desired cookie is set with <code>response.set_cookie('key', 'value', secure=False httponly=False, samesite='strict')</code></li>
  <li>JS libs (axios, react-router)</li>
  </ul>
  
  <p>Related:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/17508027/cant-access-cookies-from-document-cookie-in-js-but-browser-shows-cookies-exist">Can&#39;t access cookies from document.cookie in JS, but browser shows cookies exist</a> (httpOnly)</li>
  <li><a href="https://stackoverflow.com/questions/6217795/cant-access-a-cookie-using-document-cookie-in-js">Can&#39;t access a cookie using document.cookie in JS</a> (httpOnly)</li>
  </ul>
  
  <p><strong>Login page (JSX)</strong></p>
  
  <pre class="lang-js prettyprint-override"><code>    import React, { useState } from "react";
      import { Redirect } from "react-router-dom";
      import axios from "axios";
  
      /**
       * We're using cookies.js to read cookies.
       * Source: https://github.com/madmurphy/cookies.js
       */
      function hasItem(sKey) {
        return new RegExp(
          "(?:^|;\\s*)" +
            encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&amp;") +
            "\\s*\\="
        ).test(document.cookie);
      }
  
      export const LoginPage = () =&gt; {
        const [isAuthenticated, setIsAuthenticated] = useState(false);
        const [username, setUsername] = useState("");
        const [password, setPassword] = useState("");
  
        function handleSubmit(e) {
          e.preventDefault();
  
          function onSuccess(response) {
            // handle response
            // [...]
  
            // sometimes console.log(document.cookie) returns empty string
            if (hasItem("auth_cookie")) {
              setIsAuthenticated(true);
            } else {
              console.warn("Cookie not found!");
            }
          }
  
          function onFailure(error) {
            // handle error
          }
  
          const conf = {
            headers: new Headers({
              "Content-Type": "application/json; charset=UTF-8",
              Origin: window.location.origin
            })
          };
  
          axios
            .post("/api/login/", { username, password }, conf)
            .then(response =&gt; {
              onSuccess(response);
            })
            .catch(error =&gt; {
              onFailure(error);
            });
        }
  
        if (isAuthenticated) {
          return &lt;Redirect to="/start" /&gt;;
        }
  
        return (
          &lt;div className="login-page"&gt;
            &lt;form
              name="login-form"
              method="post"
              onSubmit={e =&gt; handleSubmit(e)}
              action="api/login"
              target="hiddenFrame"
            &gt;
              &lt;iframe className="invisible-frame" src="" name="hiddenFrame" /&gt;
              &lt;div&gt;
                &lt;label htmlFor="username"&gt;Email&lt;/label&gt;
                &lt;input
                  name="username"
                  type="text"
                  onChange={e =&gt; setUsername(e.target.value)}
                /&gt;
              &lt;/div&gt;
              &lt;div&gt;
                &lt;label htmlFor="password"&gt;Password&lt;/label&gt;
                &lt;input
                  name="password"
                  type="password"
                  onChange={e =&gt; setPassword(e.target.value)}
                /&gt;
              &lt;/div&gt;
  
              &lt;button type="submit"&gt;Submit&lt;/button&gt;
            &lt;/form&gt;
          &lt;/div&gt;
        );
      };
  </code></pre>
  
  <p><strong>Routing (JSX)</strong></p>
  
  <pre><code>    import React from "react";
      import { Route, Redirect } from "react-router-dom";
  
      const RootLayout = () =&gt; {
        return (
          &lt;div className="root-layout"&gt;
            &lt;Switch&gt;
              &lt;PublicRoute path="/login" component={LoginPage} /&gt;
              &lt;PrivateRoute path="/" component={App} /&gt;
            &lt;/Switch&gt;
          &lt;/div&gt;
        );
      };
  
      /**
       * Component that handles redirection when user is logged in already
       */
      const PublicRoute = ({ component: ChildComponent, ...remainingProps }) =&gt; {
        let isAuthenticated = hasItem("auth_cookie");
        return (
          &lt;Route
            render={props =&gt;
              isAuthenticated ? &lt;Redirect to="/" /&gt; : &lt;ChildComponent {...props} /&gt;
            }
            {...remainingProps}
          /&gt;
        );
      };
  
      /**
       * Component that handles redirection when user has been logged out.
       * E.g. when authentication cookie expires.
       */
      const PrivateRoute = ({ component: ChildComponent, ...remainingProps }) =&gt; {
        let isAuthenticated = hasItem("auth_cookie");
        return (
          &lt;Route
            render={props =&gt;
              !isAuthenticated ? (
                &lt;Redirect to="/login" /&gt;
              ) : (
                &lt;ChildComponent {...props} /&gt;
              )
            }
            {...remainingProps}
          /&gt;
        );
      };
  
      const App = () =&gt; (
        &lt;Switch&gt;
          &lt;Route exact path="/" render={() =&gt; &lt;Redirect to="/start" /&gt;} /&gt;
          &lt;Route exact path="/start" component={StartPage} /&gt;
          &lt;Route exact path="/blog" component={BlogPage} /&gt;
          {/*...*/}
        &lt;/Switch&gt;
      );
  </code></pre>
  
  <p><code>* I know, that's probably not how a post should start...</code></p>