我对反应世界和整个堆栈世界还是陌生的,但是我一直在不停地寻找以下问题的答案,并且一定会得到一些指导。
我正在使用React和Express创建一个应用程序。它需要身份验证,所以我打算使用Passport进行帮助。客户端JS使用React Routers浏览网站。没关系,但是我的问题是浏览器发出的初始GET请求。
我将首先描述我的特定应用程序要求,然后概括我不了解的内容。
正如我所说,我的应用程序需要OAuth2身份验证。如果您尝试在我的网站上获取路径,但尚未登录,则只需加载登录页面即可。如果您已登录,请照常加载并找到路径。与facebook类似,我希望登录URL与“提要”页面相同。类似于facebook.com的“ /”路由是登录页面还是新Feed(取决于您是否登录)的方式,我希望得到同样的结果。
据我了解,Passport通过检查请求标头在后端进行身份验证。因此,我了解到我应该拥有某种中间件,该中间件说“如果用户已登录,请继续进行操作,否则将呈现登录页面”……这是如何完成的?代码是什么样的?我对Express的唯一经验来自于一个介绍类,该类使用res.render发送回HTML文件,并将其通过某些模板引擎(如把手)传递。但是我不知道它如何与反应路线一起工作。我还会使用res.render()吗?还有吗
比方说,我的index.html具有根div来注入反应。如果我不得不猜测的话,我将把带有路由的.js文件发送回index.html页面,并在后端以某种方式将我希望它与我的响应路由匹配的路由(无论是登录名还是用户名)发送回去要求)?
更一般地说,我想我只是对如何使用React路由向网站的初始请求感到困惑。 1)服务器如何与所有内容交互以呈现我所要求的? 2)代码将是什么样子。我对React的唯一经验是来自一个基本的Udemy课程,该课程仅使用“ react-scripts start”来呈现页面。
花了整整一天的时间搜索这个问题后,我才想到了SSR,这是它自己的难题,我甚至不确定它是否需要帮助。是吗?
我显然缺少一些基本知识,因为这确实使我绊倒了,因此,如果您有任何学习的资源,只需将其发布即可。谢谢!
答案 0 :(得分:1)
我认为您正在苦苦挣扎的根本鸿沟源于大量的“入门课程”,它们将整个浏览器客户端推到了应用服务器中,以使事情迅速启动并运行,例如,Node服务器渲染了整个React应用并以API的身份运行...
// Ajax request from React app to: http://example.com/api
app.use('/api/*'),()=> {
res.send({ <!-- some JSON object -->})
})
// User visits in browser: http://example.com/**/*
app.use('/*',()=>{
res.render(<!-- entire React App sent to browser -->)
})
第一个请求(假设用户不访问/ api / *)只会发送React包。客户端中进一步的用户导航通常会将来自React应用的XHR请求(或打开的WebSocket)发送到在同一节点程序上运行的Express路由。
在许多情况下,将程序的这些部分分开是有意义的,例如,可以从与请求数据的位置完全不同的位置传递响应。这样做的原因很多,但是优化计算资源以满足其对CPU,内存,网络等的不同需求以及代码/部署的可管理性是我的主要理由。
例如...
用户访问:http://example.com *
反应
基本上高的响应会影响浏览器的本机“位置”功能(域名后显示的内容)。因此,初始页面加载后的所有事件(按钮单击等)都完全由React在内部处理,并使用这些路由来确定要显示的内容或要通过Ajax(XHR)从API提取的数据。
如果用户执行硬页重新加载,则该请求将返回到服务器,并将再次执行整个周期
反应路由器
允许您同时做两件事...
SSR
我只是玩弄SSR,所以我可以与之交谈,但是它提供了极低的初始渲染延迟,可以在1个网络请求中完成,因此您想在程序的重要区域使用它。< / p>
不确定是否可以回答您的问题,但是请告诉我您是否希望我详细说明什么或提供一些更详细的资源。
答案 1 :(得分:0)
我了解您的努力,因为在将前端与后端(尤其是React和Node)结合时必须自己解决。首先,我们知道浏览器/客户端将始终向服务器发起请求,因此React Router如何控制路由?好吧,它实际上很简单,您所要做的就是从快递服务器的任何路径返回整个react app。该代码将如下所示:
const express = require('express');
const app = express();
app.get('/*', (req, res, next) => {
// Return React App index.html
});
app.listen(3000);
一旦React应用在用户浏览器上呈现(不必担心路径,因为React将基于您在客户端编写的代码根据URL自动呈现,因此它还将处理身份验证与提要页面)当它扫描您的本地存储,Cookie等)时,它将控制路由,而不是发送到快递服务器的请求。但是,当我们从服务器请求数据时会发生什么情况,它会在每个路由上返回react app,因此我们需要设置一个api路由来处理任何数据请求。
app.get('/api/v1/*', (req, res, next) {
// Return some data in json format
});
希望这能使您了解所需的内容。
答案 2 :(得分:0)
对于经验较少的开发人员来说,SSR有点混乱,让我们暂时忘记它。
假设前端JavaScript(React)和后端Javascript(NodeJS)是两个单独的应用程序,并且它们通过API相互通信,将会更容易。
根据您是否登录
,此处显示显示登录组件和 Feed 组件的代码。import React, { Component } from "react";
import axios from "axios";
class Home extends Component {
constructor() {
const accessToken = localStorage.getItem("accessToken");
this.state = {
accessToken,
feeds: []
};
}
componentDidMount() {
if (this.state.accessToken) {
axios(`api/feeds?accessToken=${this.state.accessToken}`).then(({ data }) => {
this.setState({
feeds: data
});
});
}
}
render() {
if (this.state.accessToken) {
return <FeedsComponent feeds={this.state.feeds} />;
}
return <LoginComponent />;
}
}
这是您的后端
const express = require("express");
const app = express();
app.get('/api/feeds', (req, res, ) => {
const feeds = [
{},
{}
]
res.status(200).json(feeds);
});
app.listen(3001);
请记住,它们是两个单独的应用程序,它们可以位于两个不同的文件夹,不同的服务器,不同的端口中。