Fetch API在React Native项目中使用redirect: ‘manual’时无法捕获重定向。

huangapple go评论70阅读模式
英文:

Fetch API does not catch redirects with redirect: 'manual' in React Native project

问题

我在我的React Native项目中使用Fetch API。我向服务器发送HTTP POST请求,服务器期望提供用户名和密码。如果登录成功,服务器会在登录页面中设置会话cookie,然后重定向到另一个名为Blog的网页。Fetch API接收来自Blog的响应,但没有会话cookie。因此,我需要捕获重定向并在重定向发生之前存储会话cookie。

在文档中提到redirect: 'manual'应该可以解决问题。然而,我仍然收到来自最后一个页面的响应。Fetch API没有看到重定向 - response.redirected返回undefined。但请求和响应的URL是不同的。可能出了什么问题?

const url = '网站的URL(无法向您显示)';

// 登录请求
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: ${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('!响应类型!');
      console.log(response.type);
      console.log('!已重定向!');
      console.log(response.redirected);
      console.log('!响应控制台日志!');
      console.log(response.url);
      console.log('!响应状态控制台日志!');
      console.log(response.status);
      return response.headers;
    })
    .then((headers) => {
      console.log('!每个标头!');
      headers.forEach((value, key) => {
        console.log(`${key} ==> ${value}`);
      });
      return headers;
    })
    .catch((error) => console.log(`错误:${error}`));
};

export { login };

以下是浏览器中的网络活动截图:

登录:
Fetch API在React Native项目中使用redirect: ‘manual’时无法捕获重定向。

Blog:
Fetch API在React Native项目中使用redirect: ‘manual’时无法捕获重定向。

以下是日志:

LOG !响应类型!
LOG 默认
LOG !已重定向!
LOG 未定义
LOG !响应控制台日志!
LOG https://.../Blog.xhtml?faces-redirect=true&dswid=-8890
LOG !响应状态控制台日志!
LOG 200
LOG !每个标头!
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
英文:

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:
Fetch API在React Native项目中使用redirect: ‘manual’时无法捕获重定向。

Blog:
Fetch API在React Native项目中使用redirect: ‘manual’时无法捕获重定向。

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

答案1

得分: 1

手动重定向目前在 React Native 中的 Fetch API 上不起作用(请参见此处)。

英文:

Currently manual redirects does not work with the fetch api on react-native (see here)

答案2

得分: -1

请使用错误而不是手动

因为使用手动方式筛选重定向可能允许重定向伪造,所以在调用fetch()时,您应该将重定向模式设置为"error",而不是手动方式。

参考链接:https://developer.mozilla.org/en-US/docs/Web/API/Response/redirected#disallowing_redirects

英文:

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

huangapple
  • 本文由 发表于 2023年7月23日 22:53:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76748887.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定