Heroku ReactJS 应用程序。 Home 路由功能正常,但是当我尝试另一条路由时,它显示为 404 Not Found
Heroku ReactJS app. Home route is functional, but when I try another route it shows up as 404 Not Found
我正在尝试为我朋友的学校项目制作一个类似于 sport/tinder 的应用程序。它在我的本地主机上很好地组合在一起,但对他来说,这是在线托管它的要求。不是托管方面的专业人士,但我对 Heroku 有点熟悉。我为我的应用程序使用了客户端和服务器端,因此我构建了客户端并将其放入服务器端文件夹中。该服务器端托管在 Heroku 页面上并显示我的应用程序的首页。但是每当我尝试登录时,它都不起作用,并且我在控制台中收到此错误消息。
GET https://[app].herokuapp.com/dashboard 404 (Not Found)
Heroku 网页是这样说的。
Cannot GET /dashboard
我知道还有很多其他人也有同样的问题。我尝试了很多解决方案,我认为我的路由可能有问题。我是 ReactJS 的新手,所以我真的不知道如何路由,例如工作。而且我更像是一名数据科学家,而不是一名软件工程师,但我总是渴望学习,这就是为什么我抓住机会学习这个新的 'language'。所以说到问题的时候我可能是错的。
这是我用来登录的功能。这个函数在我的客户端,所以我不确定它是否在我构建到我的服务器端时传输。
const handleSubmit = async (e) => {
e.preventDefault()
try {
if( isSignUp && ( password !== confirmPassword)) {
setError('Passwords need to match!')
return
}
const response = await axios.post(`https://[app].herokuapp.com/${isSignUp ? 'signup' : 'login'}`, { email, password })
setCookie('AuthToken', response.data.token)
setCookie('UserId', response.data.userId)
const success = response.status === 201
if (success && isSignUp) navigate('/onboarding')
if (success && !isSignUp) navigate('/dashboard')
window.location.reload()
} catch (error) {
console.log(error)
}
}
我的index.js服务器的header
const PORT = process.env.PORT || 8000
const express = require('express')
const {MongoClient} = require('mongodb')
const {v1: uuidv4} = require('uuid')
const jwt = require('jsonwebtoken')
const cors = require('cors')
const bcrypt = require('bcrypt')
require('dotenv').config()
const uri = process.env.URI
const app = express()
app.use(cors())
app.use(express.json())
app.use(express.static(__dirname + "/public"));
app.get('/', (req, res) => {
res.json('Hello to my app')
})
来自我的 index.js 服务器的注册
app.post('/signup', async (req, res) => {
const client = new MongoClient(uri)
const {email, password} = req.body
const generateUserId = uuidv4()
const hashedPassword = await bcrypt.hash(password, 10)
try {
await client.connect()
const database = client.db('app-data')
const users = database.collection('users')
const existingUser = await users.findOne({email})
if (existingUser) {
return res.status((409).send('User already exists. Please login'))
}
const sanitizedEmail = email.toLowerCase()
const data = {
user_id: generateUserId,
email: sanitizedEmail,
hashed_password: hashedPassword
}
const insertedUser = await users.insertOne(data)
const token = jwt.sign(insertedUser, sanitizedEmail, {
expiresIn: 60 * 24,
})
res.status(201).json({token, userId: generateUserId})
} catch (err) {
console.log(err)
} finally {
await client.close()
}
})
从我的index.js服务器登录
app.post('/login', async (req, res) => {
const client = new MongoClient(uri)
const {email, password} = req.body
try {
await client.connect()
const database = client.db('app-data')
const users = database.collection('users')
const user = await users.findOne({email})
const correctPassword = await bcrypt.compare(password, user.hashed_password)
if (user && correctPassword) {
const token = jwt.sign(user, email, {
expiresIn: 60 * 24
})
res.status(201).json({token, userId: user.user_id})
}
res.status(400).send('Invalid Credentials')
} catch (err) {
console.log(err)
} finally {
await client.close()
}
})
欢迎任何帮助。我希望我包含了足够的代码示例,如果您需要更多,请回复 ;)
编辑
我的 package.json 服务器目录中的文件。
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"start:backend": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
我的 package.json 客户端目录中的文件。
{
"name": "funfit",
"homepage": "https://[app].herokuapp.com/",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.26.1",
"react": "^17.0.2",
"react-cookie": "^4.1.1",
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
"react-tinder-card": "^1.4.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
"start:frontend": "./node_modules/.bin/react-scripts start",
"build": "./node_modules/.bin/react-scripts build",
"test": "./node_modules/.bin/react-scripts test",
"eject": "./node_modules/.bin/react-scripts eject"
},
这是我服务器的配置
/* import */
const path = require("path");
app.use(express.static(__dirname + "/../client/build"));
app.get("*", (req, res) => {
// send index.html
let indexPath = path.join(__dirname, "/../client/build/index.html")
res.sendFile(indexPath);
});
看看是否可行。我认为您的代码的问题是只发送了主路由,因为只给出了“/”,但不确定。
确保你的目录名指向你的构建目录,因为它现在只指向 public
我正在尝试为我朋友的学校项目制作一个类似于 sport/tinder 的应用程序。它在我的本地主机上很好地组合在一起,但对他来说,这是在线托管它的要求。不是托管方面的专业人士,但我对 Heroku 有点熟悉。我为我的应用程序使用了客户端和服务器端,因此我构建了客户端并将其放入服务器端文件夹中。该服务器端托管在 Heroku 页面上并显示我的应用程序的首页。但是每当我尝试登录时,它都不起作用,并且我在控制台中收到此错误消息。
GET https://[app].herokuapp.com/dashboard 404 (Not Found)
Heroku 网页是这样说的。
Cannot GET /dashboard
我知道还有很多其他人也有同样的问题。我尝试了很多解决方案,我认为我的路由可能有问题。我是 ReactJS 的新手,所以我真的不知道如何路由,例如工作。而且我更像是一名数据科学家,而不是一名软件工程师,但我总是渴望学习,这就是为什么我抓住机会学习这个新的 'language'。所以说到问题的时候我可能是错的。
这是我用来登录的功能。这个函数在我的客户端,所以我不确定它是否在我构建到我的服务器端时传输。
const handleSubmit = async (e) => {
e.preventDefault()
try {
if( isSignUp && ( password !== confirmPassword)) {
setError('Passwords need to match!')
return
}
const response = await axios.post(`https://[app].herokuapp.com/${isSignUp ? 'signup' : 'login'}`, { email, password })
setCookie('AuthToken', response.data.token)
setCookie('UserId', response.data.userId)
const success = response.status === 201
if (success && isSignUp) navigate('/onboarding')
if (success && !isSignUp) navigate('/dashboard')
window.location.reload()
} catch (error) {
console.log(error)
}
}
我的index.js服务器的header
const PORT = process.env.PORT || 8000
const express = require('express')
const {MongoClient} = require('mongodb')
const {v1: uuidv4} = require('uuid')
const jwt = require('jsonwebtoken')
const cors = require('cors')
const bcrypt = require('bcrypt')
require('dotenv').config()
const uri = process.env.URI
const app = express()
app.use(cors())
app.use(express.json())
app.use(express.static(__dirname + "/public"));
app.get('/', (req, res) => {
res.json('Hello to my app')
})
来自我的 index.js 服务器的注册
app.post('/signup', async (req, res) => {
const client = new MongoClient(uri)
const {email, password} = req.body
const generateUserId = uuidv4()
const hashedPassword = await bcrypt.hash(password, 10)
try {
await client.connect()
const database = client.db('app-data')
const users = database.collection('users')
const existingUser = await users.findOne({email})
if (existingUser) {
return res.status((409).send('User already exists. Please login'))
}
const sanitizedEmail = email.toLowerCase()
const data = {
user_id: generateUserId,
email: sanitizedEmail,
hashed_password: hashedPassword
}
const insertedUser = await users.insertOne(data)
const token = jwt.sign(insertedUser, sanitizedEmail, {
expiresIn: 60 * 24,
})
res.status(201).json({token, userId: generateUserId})
} catch (err) {
console.log(err)
} finally {
await client.close()
}
})
从我的index.js服务器登录
app.post('/login', async (req, res) => {
const client = new MongoClient(uri)
const {email, password} = req.body
try {
await client.connect()
const database = client.db('app-data')
const users = database.collection('users')
const user = await users.findOne({email})
const correctPassword = await bcrypt.compare(password, user.hashed_password)
if (user && correctPassword) {
const token = jwt.sign(user, email, {
expiresIn: 60 * 24
})
res.status(201).json({token, userId: user.user_id})
}
res.status(400).send('Invalid Credentials')
} catch (err) {
console.log(err)
} finally {
await client.close()
}
})
欢迎任何帮助。我希望我包含了足够的代码示例,如果您需要更多,请回复 ;)
编辑
我的 package.json 服务器目录中的文件。
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"start:backend": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
我的 package.json 客户端目录中的文件。
{
"name": "funfit",
"homepage": "https://[app].herokuapp.com/",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.26.1",
"react": "^17.0.2",
"react-cookie": "^4.1.1",
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
"react-tinder-card": "^1.4.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
"start:frontend": "./node_modules/.bin/react-scripts start",
"build": "./node_modules/.bin/react-scripts build",
"test": "./node_modules/.bin/react-scripts test",
"eject": "./node_modules/.bin/react-scripts eject"
},
这是我服务器的配置
/* import */
const path = require("path");
app.use(express.static(__dirname + "/../client/build"));
app.get("*", (req, res) => {
// send index.html
let indexPath = path.join(__dirname, "/../client/build/index.html")
res.sendFile(indexPath);
});
看看是否可行。我认为您的代码的问题是只发送了主路由,因为只给出了“/”,但不确定。
确保你的目录名指向你的构建目录,因为它现在只指向 public