1

React 似乎弄乱了我的会话?当我通过 fetch 发出请求时,会话数据没有被保存,结果如下:

Session {
  cookie:
   { path: '/',
     _expires: 2019-12-31T07:36:13.407Z,
     originalMaxAge: 7200000,
     httpOnly: true,
     sameSite: true,
     secure: false },
  user: { userId: '5ddc90090b5f01596e1450f4', username: 'Test' } }
::1 - - [Tue, 31 Dec 2019 05:36:13 GMT] "POST /api/session HTTP/1.1" 200 55 "http://localhost:3000/login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
Session {
  cookie:
   { path: '/',
     _expires: 2019-12-31T07:36:19.514Z,
     originalMaxAge: 7200000,
     httpOnly: true,
     sameSite: true,
     secure: false } }
::1 - - [Tue, 31 Dec 2019 05:36:19 GMT] "GET /api/session HTTP/1.1" 200 2 "http://localhost:3000/dashboard" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"

当我使用 Insomnia 时,一切都很好:

Session {
  cookie:
   { path: '/',
     _expires: 2019-12-31T06:05:02.241Z,
     originalMaxAge: 7200000,
     httpOnly: true,
     secure: false,
     sameSite: true },
  user: { userId: '5ddc90090b5f01596e1450f4', username: 'Test' } }
::ffff:127.0.0.1 - - [Tue, 31 Dec 2019 05:40:21 GMT] "POST /api/session HTTP/1.1" 200 55 "-" "insomnia/7.0.5"
Session {
  cookie:
   { path: '/',
     _expires: 2019-12-31T06:05:02.241Z,
     originalMaxAge: 7200000,
     httpOnly: true,
     secure: false,
     sameSite: true },
  user: { userId: '5ddc90090b5f01596e1450f4', username: 'Test' } }
::ffff:127.0.0.1 - - [Tue, 31 Dec 2019 05:40:23 GMT] "GET /api/session HTTP/1.1" 200 64 "-" "insomnia/7.0.5"

看看user会话数据中的持久性如何?我不知道为什么 React 的请求中没有发生这种情况。

这是我在 React 中的登录页面(触发 POST 请求)

import React from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { login } from "../actions/session";

const Login = ({ errors, login }) => {
  const handleSubmit = e => {
    e.preventDefault();
    const user = {
      email: e.target[0].value,
      password: e.target[1].value,
    };
    login(user);
  }  

  return (
    <>
      <h1>Login</h1>
      <p>{errors}</p>
      <form onSubmit={handleSubmit}>
        <label>
          Email:
          <input type="email" name="email" />
        </label>
        <label>
          Password:
          <input type="password" name="password" />
        </label>
        <input type="submit" value="Submit" />
      </form>
      <Link to="/signup">Signup</Link>
    </>
  );
};

const mapStateToProps = ({ errors }) => ({
  errors
});

const mapDispatchToProps = dispatch => ({
  login: user => dispatch(login(user))
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Login);

这是调度的动作:

export const login = user => async dispatch => {
  const response = await apiUtil.login(user);
  const data = await response.json();

  if (response.ok) {
    return dispatch(recieveCurrentUser(data));
  }

  return dispatch(receiveErrors(data));
}

这就是我提出请求的方式

export const login = user => (
  fetch("http://localhost:8080/api/session", {
    method: "POST",
    body: JSON.stringify(user),
    headers: {
      "Content-Type": "application/json"
    }
  })
);

这是我正在获取数据的仪表板

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { logout, getUser } from '../actions/session';
import { getTransactions } from '../actions/transactions';

const uuid = require('uuid/v4');

class Dashboard extends Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    // this.props.getTransactions();
  };

  handleSubmit = () => {
    console.log("here");

    this.props.getUser();
  }

  render() {
    return (
      <div className="container">
        <h1>Hi {this.props.session.username}</h1>
        <p>You are now logged in!</p>
          {
            <div className="transactions">
            this.props.transactions.forEach(element => (
              <h1>element.title</h1>
              <p>element.uuid ? element.uuid : uuid()</p>
            ));
            </div>
          }
        <button onClick={this.props.logout}>Logout</button>
        <button onClick={this.handleSubmit}>Get Session Data</button>
        <p>{ this.props.session.username }</p>
      </div>
    );
  };
};

const mapStateToProps = ({ session, transactions }) => ({
  session,
  transactions
});

const mapDispatchToProps = dispatch => ({
  logout: () => dispatch(logout()),
  getUser: () => dispatch(getUser())
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Dashboard);

这是我发送的GET请求以执行获取会话数据的请求(在按钮中):

export const getData = () => (
  fetch("http://localhost:8080/api/session")
);

这是我要触发的动作:

export const getUser = () => async dispatch => {
  const response = await apiUtil.getData();
  const data = await response.json();

  if (response.ok) {
    return dispatch(recieveCurrentUser(data));
  }
}
4

2 回答 2

2

尝试包括credentials在你的fetch

export const login = user => (
  fetch("http://localhost:8080/api/session", {
    method: "POST",
    body: JSON.stringify(user),
    headers: {
      "Content-Type": "application/json"
    },
    credentials: 'include'
  })

);

更新

当然,如果您不在同一个域中,则必须在服务器端启用 cors...

您必须包含 express 提供的cors库。

像这样的东西:

app.use(cors({origin: 'localhost:3000', credentials:true }));
于 2019-12-31T12:05:44.710 回答
0

我假设当您的意思是 Insomnia 时,您正在谈论 HTTP 调试器,并且您正在某种反应开发服务器(例如 webpack)上运行前端代码,如果是这样,这很可能意味着您的开发服务器托管在与您的后端不同的服务器(不同的端口在此上下文中意味着不同的服务器)。由于 Insomnia 不是浏览器,因此许多限制不适用,其中之一是允许向几乎任何服务器发出请求并自由读取响应,而您的浏览器则不是这样,以启用读取响应的复杂性' 请求您需要传递一些额外的标头。

您可以在此处阅读有关如何获取的信息

关于标题本身和这里的场景

希望您的服务器配置为接受并响应 COR,否则您必须进行必要的更改。

于 2019-12-31T06:37:50.230 回答