skip to Main Content

I am using Fetch API in my React Native project. I do HTTP POST request to a server, which expects username and password. If login is succesfull, the server sets session cookie in Login page and then redirects to another web page called Blog. Fetch API receives the response from Blog, which has no session cookie. So I need to catch the redirect and store the session cookie before the redirect happens.

In documentation it says that redirect: 'manual' should do the job. However, I still get the response from the very last page. Redirect is not seen by Fetch API – response.redirected returns undefined. But the url of the request and response are different. What could potentially be wrong?

const url = 'url of a website ( cannot show it to you )';
// login request
const login = (profileName, password) => {
  const details = {
    benutzername: profileName,
    passwort: password,
  };

  const formBody = Object.keys(details)
    .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(details[key])}`)
    .join('&');

  console.log(`formBody to be sent: ${formBody}`);

  fetch(url, {
    method: 'POST',
    headers: {
      Accept:
        'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: formBody,
    redirect: 'manual',
  })
    .then((response) => {
      console.log('! response type !');
      console.log(response.type);
      console.log('! is redirected !');
      console.log(response.redirected);
      console.log('! response console log !');
      console.log(response.url);
      console.log('! response status console log !');
      console.log(response.status);
      return response.headers;
    })
    .then((headers) => {
      console.log('! headers for each !');
      headers.forEach((value, key) => {
        console.log(`${key} ==> ${value}`);
      });
      return headers;
    })
    .catch((error) => console.log(`error: ${error}`));
};

export { login };

Here are screenshots of Network Activity in browser:

Login:
Login page network activity

Blog:
Blog page network activity

Here are the logs:

LOG  ! response type !
 LOG  default
 LOG  ! is redirected !
 LOG  undefined
 LOG  ! response console log !
 LOG  https://.../Blog.xhtml?faces-redirect=true&dswid=-8890
 LOG  ! response status console log !
 LOG  200
 LOG  ! headers for each !
 LOG  cache-control ==> no-cache, no-store, must-revalidate
 LOG  content-encoding ==> gzip
 LOG  content-type ==> text/html;charset=UTF-8
 LOG  date ==> Sun, 23 Jul 2023 14:54:59 GMT
 LOG  expires ==> 0
 LOG  pragma ==> no-cache
 LOG  server ==> Apache
 LOG  set-cookie ==> dsrwid--8890=-8890; path=/; secure; Max-Age=60; Expires=Sun, 23-Jul-2023 14:55:59 GMT; SameSite=None
 LOG  vary ==> Accept-Encoding

2

Answers


  1. Instead of using the manual, try using error

    Because using redirected to manually filter out redirects can allow
    forgery of redirects, you should instead set the redirect mode to
    "error" in the init parameter when calling fetch()

    Refference : https://developer.mozilla.org/en-US/docs/Web/API/Response/redirected#disallowing_redirects

    Login or Signup to reply.
  2. Currently manual redirects does not work with the fetch api on react-native (see here). You could work around this by storing the session cookie as a piece of state, and then conditionally rendering the Login/Blog screen:

    const [cookie,setCookie] = useState(null)
    useEffect(()=>{
      login().then(res=>setCookies(res.body["path/to/cookie"])
    },[])
    return (
      <View>
        {cookie ? (
           <BlogScreen />
         ):(
           <LoginScreen />
         )}
      </View>
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search