所以我几天来一直在为这个问题而苦苦挣扎,几乎尝试了我遇到的每一个论坛建议。基本上我已经设置了一个后端服务器,以便允许自己通过节点发送电子邮件。奇怪的是,它在我的本地机器上完美运行,当我推送到 Heroku 时,它甚至可以完美地构建和部署。但是,我仍然只是提示"无法获取/"。
这是我的文件结构:
PROJETNAME
- client
^--
^-- build
^-- node_modules
^-- public
^-- src
- node_modules
- .gitignore
- package.lock.json
- package.json
- server.js
这是我在根(后端(文件夹中的package.json:
{
"name": "sendemail",
"version": "1.0.0",
"description": "",
"main": "server.js",
"devDependencies": {},
"cacheDirectories": [
"node_modules",
"client/node_modules"
],
"engines": {
"node": "8.9.x"
},
"keywords": [
"node",
"heroku",
"create-react-app",
"react"
],
"scripts": {
"start": "node server.js",
"server": "nodemon server.js",
"client":"npm run start --prefix client",
"dev":"concurrently "npm run server" "npm run client"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"keywords": [],
"author": "ANDY",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"concurrently": "^3.5.1",
"express": "^4.16.3",
"nodemailer": "^4.6.5",
"nodemon": "^1.17.5"
}
}
这是我的服务器.js
const express = require('express');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.post('/api/form', (req, res) => {
nodemailer.createTestAccount((err, account) => {
const htmlEmail = `
<h3>Contact Details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Email: ${req.body.email}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
let transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
auth: {
user: 'config',
pass: 'config'
}
});
let mailOptions = {
from: 'config',
to: 'config',
replyTo: 'config',
subject: 'New message',
text: req.body.message,
html: htmlEmail
};
transporter.sendMail(mailOptions, (err, info) => {
if(err){
return console.log(err);
}
console.log('Message sent: %s', info.message);
console.log('Message URL: %s', nodemailer.getTestMessageUrl(info));
});
});
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log('Server listening on port ' + PORT);
});
这是我在客户端文件夹中的package.json:
{
"name": "website",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:5000",
"devDependencies": {
"react-scripts": "^1.1.0"
},
"dependencies": {
"axios": "^0.18.0",
"email-validator": "^1.1.1",
"firebase": "^4.10.1",
"normalize.css": "^8.0.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-helmet": "^5.2.0",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-s-alert": "^1.4.1",
"react-scripts": "1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
我还将包括一些 Heroku 日志,因此这是在访问时从控制台进行的,上面所有配置都已到位:
2018-05-31T17:05:30.745029+00:00 heroku[web.1]: Starting process with command `npm start`
2018-05-31T17:05:33.349990+00:00 app[web.1]: Server listening on port 52364
2018-05-31T17:05:33.029353+00:00 app[web.1]:
2018-05-31T17:05:33.029370+00:00 app[web.1]: > sendemail@1.0.0 start /app
2018-05-31T17:05:33.029372+00:00 app[web.1]: > node server.js
2018-05-31T17:05:33.029374+00:00 app[web.1]:
2018-05-31T17:05:34.589991+00:00 heroku[web.1]: State changed from starting to up
2018-05-31T17:05:36.032333+00:00 heroku[router]: at=info method=GET path="/" host=tranquil-ravine-15017.herokuapp.com request_id=7c7aa9a7-e1d9-429f-9122-ea84040e7627 fwd="46.9.122.184" dyno=web.1 connect=0ms service=16ms status=404 bytes=383 protocol=https
2018-05-31T17:11:15.097815+00:00 heroku[router]: at=info method=GET path="/" host=tranquil-ravine-15017.herokuapp.com request_id=0df69ac3-e087-4b7a-a13a-84b14937c03b fwd="46.9.122.184" dyno=web.1 connect=2ms service=5ms status=404 bytes=383 protocol=https
因此,正如您在此处看到的,服务器启动时没有重大错误。最后,我还将包括最后一个构建(上传到 Heroku(:
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 369 bytes | 369.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
remote:
remote: -----> Creating runtime environment
remote:
remote: NPM_CONFIG_LOGLEVEL=error
remote: NODE_VERBOSE=false
remote: NODE_ENV=production
remote: NODE_MODULES_CACHE=true
remote:
remote: -----> Installing binaries
remote: engines.node (package.json): 8.9.x
remote: engines.npm (package.json): unspecified (use default)
remote:
remote: Resolving node version 8.9.x...
remote: Downloading and installing node 8.9.4...
remote: Using default npm version: 5.6.0
remote:
remote: -----> Restoring cache
remote: Loading 2 from cacheDirectories (package.json):
remote: - node_modules
remote: - client/node_modules (exists - skipping)
remote:
remote: -----> Building dependencies
remote: Installing node modules (package.json + package-lock)
remote: up to date in 3.189s
remote: Running heroku-postbuild
remote:
remote: > website@1.0.0 heroku-postbuild /tmp/build_83074ef79a0ec69232c64e8b290c1953
remote: > NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client
remote:
remote:
remote: > grpc@1.10.1 install /tmp/build_83074ef79a0ec69232c64e8b290c1953/client/node_modules/grpc
remote: > node-pre-gyp install --fallback-to-build --library=static_library
remote:
remote: [grpc] Success: "/tmp/build_83074ef79a0ec69232c64e8b290c1953/client/node_modules/grpc/src/node/extension_binary/node-v57-linux-x64-glibc/grpc_node.node" is installed via remote
remote:
remote: > uglifyjs-webpack-plugin@0.4.6 postinstall /tmp/build_83074ef79a0ec69232c64e8b290c1953/client/node_modules/uglifyjs-webpack-plugin
remote: > node lib/post_install.js
remote:
remote: added 305 packages, removed 220 packages and updated 1092 packages in 56.689s
remote:
remote: > website@0.1.0 build /tmp/build_83074ef79a0ec69232c64e8b290c1953/client
remote: > react-scripts build
remote:
remote: Creating an optimized production build...
remote: Compiled with warnings.
remote:
remote: ./src/components/Admin-Panel-Edit-News.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 3: 'Table' is defined but never used no-unused-vars
remote: Line 3: 'Checkbox' is defined but never used no-unused-vars
remote: Line 3: 'Modal' is defined but never used no-unused-vars
remote: Line 3: 'Popup' is defined but never used no-unused-vars
remote: Line 4: 'BrowserRouter' is defined but never used no-unused-vars
remote: Line 4: 'Route' is defined but never used no-unused-vars
remote: Line 4: 'Switch' is defined but never used no-unused-vars
remote: Line 4: 'Link' is defined but never used no-unused-vars
remote: Line 4: 'NavLink' is defined but never used no-unused-vars
remote: Line 6: 'database' is defined but never used no-unused-vars
remote: Line 24: Do not mutate state directly. Use setState() react/no-direct-mutation-state
remote: Line 82: Unexpected string concatenation of literals no-useless-concat
remote: Line 157: Unexpected string concatenation of literals no-useless-concat
remote: Line 328: 'open' is assigned a value but never used no-unused-vars
remote: Line 328: 'size' is assigned a value but never used no-unused-vars
remote: Line 344: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 344: Expected '!==' and instead saw '!=' eqeqeq
remote:
remote: ./src/components/Admin-Panel-Add-News.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 3: 'Table' is defined but never used no-unused-vars
remote: Line 3: 'Checkbox' is defined but never used no-unused-vars
remote: Line 5: 'BrowserRouter' is defined but never used no-unused-vars
remote: Line 5: 'Route' is defined but never used no-unused-vars
remote: Line 5: 'Switch' is defined but never used no-unused-vars
remote: Line 5: 'Link' is defined but never used no-unused-vars
remote: Line 5: 'NavLink' is defined but never used no-unused-vars
remote: Line 96: Unexpected string concatenation of literals no-useless-concat
remote: Line 171: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 171: Expected '!==' and instead saw '!=' eqeqeq
remote:
remote: ./src/components/Admin-Header.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 4: 'BrowserRouter' is defined but never used no-unused-vars
remote: Line 4: 'Switch' is defined but never used no-unused-vars
remote: Line 4: 'Route' is defined but never used no-unused-vars
remote: Line 5: 'performLogout' is defined but never used no-unused-vars
remote: Line 52: 'allNewMessages' is assigned a value but never used no-unused-vars
remote: Line 60: Expected '===' and instead saw '==' eqeqeq
remote: Line 78: 'showMobileMenu' is assigned a value but never used no-unused-vars
remote: Line 89: 'mobileMenuVisible' is assigned a value but never used no-unused-vars
remote: Line 94: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 96: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 101: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 102: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 102: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 108: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 109: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 112: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 117: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 118: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote: Line 118: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote:
remote: ./src/components/Admin-Panel-Messages.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 3: 'Image' is defined but never used no-unused-vars
remote: Line 3: 'Dimmer' is defined but never used no-unused-vars
remote: Line 3: 'Segment' is defined but never used no-unused-vars
remote: Line 3: 'Loader' is defined but never used no-unused-vars
remote: Line 94: Expected '===' and instead saw '==' eqeqeq
remote: Line 176: 'canShowMessages' is assigned a value but never used no-unused-vars
remote:
remote: ./src/components/Admin-Panel-News.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 3: 'Loader' is defined but never used no-unused-vars
remote: Line 3: 'Segment' is defined but never used no-unused-vars
remote: Line 3: 'Dimmer' is defined but never used no-unused-vars
remote: Line 3: 'Modal' is defined but never used no-unused-vars
remote: Line 129: Expected '===' and instead saw '==' eqeqeq
remote: Line 161: 'open' is assigned a value but never used no-unused-vars
remote: Line 161: 'size' is assigned a value but never used no-unused-vars
remote:
remote: ./src/Admin-Reset-Password.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 3: 'Message' is defined but never used no-unused-vars
remote: Line 5: 'Redirect' is defined but never used no-unused-vars
remote: Line 53: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text
remote:
remote: ./src/components/Admin-Panel-Welcome.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 23: 'form' is assigned a value but never used no-unused-vars
remote:
remote: ./src/components/Authentication.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 3: 'withRouter' is defined but never used no-unused-vars
remote:
remote: ./src/Admin-News.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote:
remote: ./src/Admin-Edit-News.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote:
remote: ./src/Admin-Read-Message.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote:
remote: ./src/Admin-Messages.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote:
remote: ./src/Admin-Add-News.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote:
remote: ./src/Admin-Welcome.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote:
remote: ./src/components/Admin-Panel-Read-Message.js
remote: Line 2: 'ReactDOM' is defined but never used no-unused-vars
remote: Line 3: 'Table' is defined but never used no-unused-vars
remote: Line 3: 'Checkbox' is defined but never used no-unused-vars
remote:
remote: Search for the keywords to learn more about each warning.
remote: To ignore, add // eslint-disable-next-line to the line before.
remote:
remote: File sizes after gzip:
remote:
remote: 265.06 KB (-103 B) build/static/js/main.34ea30f2.js
remote: 9.36 KB build/static/css/main.17f72539.css
remote:
remote: The project was built assuming it is hosted at the server root.
remote: You can control this with the homepage field in your package.json.
remote: For example, add this to build it for GitHub Pages:
remote:
remote: "homepage" : "http://myname.github.io/myapp",
remote:
remote: The build folder is ready to be deployed.
remote: You may serve it with a static server:
remote:
remote: yarn global add serve
remote: serve -s build
remote:
remote: Find out more about deployment here:
remote:
remote: http://bitlylinkhere
remote:
remote:
remote: -----> Caching build
remote: Clearing previous node cache
remote: Saving 2 cacheDirectories (package.json):
remote: - node_modules
remote: - client/node_modules
remote:
remote: -----> Pruning devDependencies
remote: Skipping because npm 5.6.0 sometimes fails when running 'npm prune' due to a known issue
remote: https://github.com/npm/npm/issues/19356
remote:
remote: You can silence this warning by updating to at least npm 5.7.1 in your package.json
remote: https://devcenter.heroku.com/articles/nodejs-support#specifying-an-npm-version
remote:
remote: -----> Build succeeded!
remote: -----> Discovering process types
remote: Procfile declares types -> (none)
remote: Default types for buildpack -> web
remote:
remote: -----> Compressing...
remote: Done: 78.9M
remote: -----> Launching...
remote: Released v23
remote: https://myherokuapphere.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
如您所见,构建中没有任何令人震惊的错误,最终 - 也已成功上传。我真的因此而发疯了。这里似乎有什么问题?我已经答应一个朋友在他的网站上集成电子邮件功能,该网站应该在下周交付,因此我感到非常紧张。任何帮助将不胜感激!提前谢谢。
啊!我想我看到了问题,哈哈。您没有从快速服务器提供索引.html文件。将此代码粘贴到服务器.js文件中。
if (process.env.NODE_ENV === 'production') {
// Exprees will serve up production assets
app.use(express.static('client/build'));
// Express serve up index.html file if it doesn't recognize route
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}