Heroku上的PERN堆栈应用程序语法错误:意外的令牌<在位置0的JSON中



我正试图在Heroku上部署我的第一个React.js应用程序。除了最重要的部分-我用来从我的Postgres数据库和Stripe API获取数据的Express.js REST API在本地主机上正常工作,但当我在Heroku上部署应用程序时,我试图访问的所有API路由都返回相同的语法错误-意外令牌<在位置0的JSON中。

我知道这个问题与我的应用程序如何路由到API有关。换句话说,fetch请求无法到达所需的端点,因此返回此语法错误,但我无法准确指出问题所在——我是不是在某个地方缺少了一个"/",我是否错误地设置了环境变量,等等。?

有人遇到过类似的问题吗?或者有人可以在下面的代码中发现这个问题吗?

package.json

{
...
"private": true,
"main": "server.js",
"homepage": "https://dj-bbq.herokuapp.com",
"engines": {
"npm": "6.14.15",
"node": "14.18.1"
},
"dependencies": {
"@formspree/react": "^2.2.4",
"@stripe/react-stripe-js": "^1.7.0",
"@stripe/stripe-js": "^1.22.0",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@userfront/react": "^0.2.22",
"cors": "^2.8.5",
"express": "^4.17.2",
"express-fileupload": "^1.2.1",
"helmet": "^5.0.1",
"jsonwebtoken": "^8.5.1",
"pg": "^8.7.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.1",
"react-scripts": "4.0.3",
"stripe": "^8.195.0",
"web-vitals": "^2.1.2"
},
"devDependencies": {
"dotenv": "^10.0.0",
"nodemon": "^2.0.15",
"source-map-explorer": "^2.5.2"
},
"scripts": {
"start": "node server.js",
"heroku-postbuild": "npm install && npm run build",
"dev-start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"analyze": "source-map-explorer 'build/static/js/*.js'",
"server": "node server.js",
"nodemon": "nodemon server.js"
},...

server.js

const express = require('express');
const helmet = require('helmet'); 
const cors = require('cors'); 
const path = require('path'); // Allows to access files through the server in our filesystem
const fileUpload = require('express-fileupload'); // Parses multipart/form-data requests, extracts the files if available, and make them available under req.files property.
/**
**  ------------- GENERAL SETUP -------------
*/
// Provides access to variables from the .env file by using process.env.REACT_APP_variable_name
require('dotenv').config();
const nodeEnv = process.env.NODE_ENV !== 'production';
const devPort = process.env.REACT_APP_server_dev_port;
const prodPort = process.env.PORT // process.env.PORT 
const devDomain = process.env.REACT_APP_dev_domain;
const prodDomain= process.env.REACT_APP_prod_domain;

const PORT = nodeEnv ? devPort : prodPort;
const domain = nodeEnv ? devDomain : prodDomain;
// CORS options
const corsOptions = {
origin: domain, // frontend_URL for heroku deployment
credentials: true ,
// Allows only the following HTTP requests to go through
methods: [
"PUT", 
"POST", 
"DELETE", 
"GET",
],
"Access-Control-Allow-Headers": [
"Origin", 
"X-Requested-With", 
"Content-Type", 
"Accept", 
"Authorization",
],
};
//* Creates the Express server instance as "app" 
const app = express();
//* MIDDLEWARE
// Called BETWEEN processing the Request and sending the Response in your application method.
app.use(helmet()); // Sets many http headers to make them more secure
app.use(cors(corsOptions)); // To allow cross origin conections (Allows our React app to make HTTP requests to Express application)        

// Instead of using body-parser middleware, use the new Express implementation of the same thing
app.use(express.json()); // To recognize the incoming Request Object (req.body) as a JSON Object
app.use(express.urlencoded({ extended: true })); // To recognize the incoming Request Object as strings or arrays
app.use(fileUpload({
createParentPath: true
})); // Enables file uploading
//* HEROKU MIDDLEWARE
if (process.env.NODE_ENV !== 'production') {
// To load static files or client files from here http://localhost:3000/images/kitten.jpg
app.use(express.static(path.join(__dirname, 'public')));
} else if (process.env.NODE_ENV === 'production') {
// Serve static files - makes the build folder accessible to app.
app.use(express.static(path.joins(__dirname, 'build'))); 
// app.use(express.static(path.resolve(__dirname, 'build'))); 
}
/**
** -------------- SERVER ----------------
*/

// Determines the PORT and enables LISTENing for requests on the PORT (http://localhost:8000)

app.listen(PORT, () => {
console.debug(`Server is listening at http://localhost:${PORT}`);
});

/**
** ------- ROUTES / ENDPOINTS ---------
*/
// Go to /test to make sure the basic API functioning is working properly
app.get('/test', (req, res) => {
res.status(200).send('The Basic API endpoints are working.')
});
// Imports all of the routes from ./routes/index.js
app.use(require('./app-server/routes/allRoutes'));
// If req comes from one of these domains (origins), then allow the request with CORS.
app.use((req, res, next) => {
const corsWhitelist = [
domain,
];
if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
}
next();
});

我在另一个文件中为未知路由设置了一个包罗万象的路由(路由器(

//* HEROKU - catch all for unrecognised routes
if (process.env.NODE_ENV === 'production') {
// Serve index.html file if it doesn't recognize the route
router.get('*', (req, res, next) => { // or * instead of /
res.sendFile(path.join(__dirname, 'build', 'index.html')); // resolve instead of join
})
}

这里是一个提取请求的例子

const [recipes, setRecipes] = useState([]);

useEffect(() => {
let interval;
const fetchData = async () => {
try {
// const url = 'http://localhost:8000/recipes/display';
const url = `${customProxy}/recipes/display`;
const response = await fetch(url);
const json = await response.json();
setRecipes(json);

} catch(error) {
// console.error(error);
alert("Recipe displaying:" + error);
}
};
fetchData();
interval = setInterval(() => {
fetchData()
}, 86 * 1000)
return () => {
clearInterval(interval)
}
}, []); // Determine swhen to re-use useEffect, if this changes.

提前感谢您花时间考虑问题的解决方案

更新1

我开始第n次浏览我的项目,之前我遵循Heroku上的指南部署了我的PERN应用程序。指南建议使用mars/create react app buildpack来部署该应用程序,但在阅读了该构建包的文档后,它明确表示,该构建包仅适用于静态react应用程序,而不适用于具有自己的自定义node.js服务器的react应用程序。

在这种情况下,我将使用mars/heroku-cra节点。

我一直在遵循关于如何设置文件夹结构等的文档,但现在,当我部署应用程序时,Heroku会通知我以下内容。。。

-----> Building on the Heroku-20 stack
-----> Using buildpacks:
1. https://github.com/mars/heroku-cra-node
-----> App not compatible with buildpack: https://github.com/mars/heroku-cra-node
bash: /tmp/codon/tmp/buildpacks/d07ae047a3685d9cfb39224105301a7dbdbfbe9c/bin/detect: No such file or directory
More info: https://devcenter.heroku.com/articles/buildpacks#detection-failure
!     Push failed

我知道这个想法是我的文件夹结构不符合构建包的要求,但我严格遵循它的文档。

有人有使用这个构建包将PERN应用程序部署到Heroku的经验吗?

我注意到我的这个问题仍然没有答案。

最后的问题是,我试图使用Heroku免费计划,但我的应用程序太";"大";为此,我要么需要将后端和前端拆分为两个应用程序,要么使用付费计划。

最后,我实际上把我的托管服务提供商从Heroku换成了Digital Ocean。该应用程序仍在他们的服务器上,现在可以工作了-https://dj-bbq-i5gdc.ondigitalocean.app/。

相关内容

最新更新