HTTPS 问题节点服务器 MERN 堆栈
HTTPS issue node server MERN stack
几个小时以来,我一直在疯狂地尝试让我的电子邮件正常工作。
这是网站:https://www.shafirpl.com/contact
我有一个 React 应用程序托管在与 node.js 应用程序相同的服务器(数字海洋水滴)上。域名(shafirpl.com)有来自 cloudflare 的 SSL 证书。 node.js 应用程序在端口 4000 上 运行 而反应应用程序在端口 80 上。所以现在发生的是反应生产构建在该 IP [=24 的端口 80 上 运行 =],当用户单击发送按钮时,我有一个 axios post 请求。当它在我的本地机器上时,它的工作原理是 axios 请求使用“http://localhost:4000/email". But when I deployed on the server and changed the URL to "http://myServerIpAddress:4000/email" I get the error that says I have to send the request via https. I am not sure how to generate an SSL certificate so that my front end react app can commit the axios request and don't have the issue. I have tried to follow certbot tutorial but it seems like certbot requires a specific domain name. SO what I did is that I created key-cert pairs for my domain name (shafirpl.com) using this tutorial (https://dev.to/omergulen/step-by-step-node-express-ssl-certificate-run-https-server-from-scratch-in-5-steps-5b87) 并且在我的 server.js 文件(node.js 应用程序大脑)中使用,如下所示:
const express = require("express");
// const connectDB = require("./config/db");
const path = require("path");
const https = require("https");
const fs = require("fs");
// routes variables
const emailRoute = require("./routes/email");
const resumeRoute = require("./routes/resume");
// const authRoute = require("./routes/api/auth");
const app = express();
var cors = require("cors");
// var corsOptions = {
// origin: "*",
// optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
// };
app.use(cors());
app.options("*", cors());
// Connect Database
// connectDB();
// Middleware initialization
/*
* Usually we used to install body parser and do
* app.use(bodyparser.json()). But now bodyparser comes
* packaged with express. So we just have to do express.json()
* to use bodyparser
*/
app.use(express.json({ extended: false }));
// use this when on my pc
// app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "http://localhost:3000"); // update to match the domain you will make the request from
// res.header(
// "Access-Control-Allow-Headers",
// "Origin, X-Requested-With, Content-Type, Accept"
// );
// next();
// });
// use this on produnction
// app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
// res.header(
// "Access-Control-Allow-Headers",
// "Origin, X-Requested-With, Content-Type, Accept"
// );
// next();
// });
// app.get("/", (req,res) => {res.send('API Running')});
// Define Routes
app.get("/", (req, res) => {
res.send("Server Running");
});
app.use("/email", emailRoute);
app.use("/resume", resumeRoute);
// app.use("/api/auth", authRoute);
// app.use("/api/profile", profileRoute);
// app.use("/api/posts", postsRoute);
// // serve static assets in production
// if (process.env.NODE_ENV === "production") {
// // set static folder
// app.use(express.static("client/build"));
// app.get("*", (req, res) => {
// res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
// });
// }
/*
* This means when the app will be deployed to heroku, it will
* look for a port specified by heroku. But since right now
* locally we don't have that, we will be running the app on
* port 5000
*/
// const PORT = process.env.PORT || 4000;
// app.listen(PORT, () => {
// console.log(`Server started on port ${PORT}`);
// });
app.listen(4000);
// comment out this line when testing on localhost
const httpsServer = https.createServer(
{
key: fs.readFileSync("/etc/letsencrypt/live/shafirpl.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/shafirpl.com/fullchain.pem"),
},
app
);
httpsServer.listen(443, () => {
console.log("HTTPS Server running on port 443");
});
而在我的axios.post中,我是这样使用的
const url = "https://shafirpl.com:443/email";
const sendMessage = async () => {
const config = {
headers: {
'Content-Type': 'application/json',
}
}
const body = JSON.stringify({ name, email, company, message });
try {
const res = await axios.post(url, body, config);
console.log(res);
clearForm();
showSuccessMessage();
} catch (error) {
console.log(error);
showFailureMessage();
}
}
const showFailureMessage = () => {
setFailureAlert(true);
setTimeout(() => {
setFailureAlert(false)
}, 3000);
}
但是现在我又遇到了这个错误:
对“https://shafirpl.com/email' from origin 'https://www.shafirpl.com”处的 XMLHttpRequest 的访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在 'Access-Control-Allow-Origin' header。
我实际上不知道如何解决这个问题,因为我对整个 MERN 堆栈构建还很陌生。谁能帮我这个?我只想使用 axios
发送电子邮件
我有同样的问题 - 我做了什么,我从服务器和客户端删除了显式端口。然后我注意到我正在点击 http://mydomain.... please try accessing it from https://mydomain...这对我有用 :) 希望对您有所帮助!
我想我已经解决了这个问题。我决定通过我的 node.js 应用程序来提供我的 React 构建,而不是 运行 2 个不同的应用程序。我的做法是这样的:
const express = require("express");
// const connectDB = require("./config/db");
const path = require("path");
// routes variables
const emailRoute = require("./routes/email");
const resumeRoute = require("./routes/resume");
const app = express();
app.use(express.json({ extended: false }));
app.use("/api/email", emailRoute);
app.use("/api/resume", resumeRoute);
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
app.listen(80);
然后根据我的 axios 请求,我就这样做了:
const url = "/api/email"; const sendMessage = async () => {
const config = {
headers: {
'Content-Type': 'application/json',
}
}
const body = JSON.stringify({ name, email, company, message });
try {
const res = await axios.post(url, body, config);
console.log(res);
clearForm();
showSuccessMessage();
} catch (error) {
console.log(error);
showFailureMessage();
}
}
目前一切正常。
对于发送文件下载的简历,我不得不使用 /api/resume 而不是
像这样
<Nav.Link eventKey="6" activeClassName="active-nav" href="https://shafirpl.com/api/resume" target="_blank" rel="noopener noreferrer">Resume</Nav.Link>
现在简历下载也正常
感谢大家的帮助
几个小时以来,我一直在疯狂地尝试让我的电子邮件正常工作。 这是网站:https://www.shafirpl.com/contact 我有一个 React 应用程序托管在与 node.js 应用程序相同的服务器(数字海洋水滴)上。域名(shafirpl.com)有来自 cloudflare 的 SSL 证书。 node.js 应用程序在端口 4000 上 运行 而反应应用程序在端口 80 上。所以现在发生的是反应生产构建在该 IP [=24 的端口 80 上 运行 =],当用户单击发送按钮时,我有一个 axios post 请求。当它在我的本地机器上时,它的工作原理是 axios 请求使用“http://localhost:4000/email". But when I deployed on the server and changed the URL to "http://myServerIpAddress:4000/email" I get the error that says I have to send the request via https. I am not sure how to generate an SSL certificate so that my front end react app can commit the axios request and don't have the issue. I have tried to follow certbot tutorial but it seems like certbot requires a specific domain name. SO what I did is that I created key-cert pairs for my domain name (shafirpl.com) using this tutorial (https://dev.to/omergulen/step-by-step-node-express-ssl-certificate-run-https-server-from-scratch-in-5-steps-5b87) 并且在我的 server.js 文件(node.js 应用程序大脑)中使用,如下所示:
const express = require("express");
// const connectDB = require("./config/db");
const path = require("path");
const https = require("https");
const fs = require("fs");
// routes variables
const emailRoute = require("./routes/email");
const resumeRoute = require("./routes/resume");
// const authRoute = require("./routes/api/auth");
const app = express();
var cors = require("cors");
// var corsOptions = {
// origin: "*",
// optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
// };
app.use(cors());
app.options("*", cors());
// Connect Database
// connectDB();
// Middleware initialization
/*
* Usually we used to install body parser and do
* app.use(bodyparser.json()). But now bodyparser comes
* packaged with express. So we just have to do express.json()
* to use bodyparser
*/
app.use(express.json({ extended: false }));
// use this when on my pc
// app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "http://localhost:3000"); // update to match the domain you will make the request from
// res.header(
// "Access-Control-Allow-Headers",
// "Origin, X-Requested-With, Content-Type, Accept"
// );
// next();
// });
// use this on produnction
// app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
// res.header(
// "Access-Control-Allow-Headers",
// "Origin, X-Requested-With, Content-Type, Accept"
// );
// next();
// });
// app.get("/", (req,res) => {res.send('API Running')});
// Define Routes
app.get("/", (req, res) => {
res.send("Server Running");
});
app.use("/email", emailRoute);
app.use("/resume", resumeRoute);
// app.use("/api/auth", authRoute);
// app.use("/api/profile", profileRoute);
// app.use("/api/posts", postsRoute);
// // serve static assets in production
// if (process.env.NODE_ENV === "production") {
// // set static folder
// app.use(express.static("client/build"));
// app.get("*", (req, res) => {
// res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
// });
// }
/*
* This means when the app will be deployed to heroku, it will
* look for a port specified by heroku. But since right now
* locally we don't have that, we will be running the app on
* port 5000
*/
// const PORT = process.env.PORT || 4000;
// app.listen(PORT, () => {
// console.log(`Server started on port ${PORT}`);
// });
app.listen(4000);
// comment out this line when testing on localhost
const httpsServer = https.createServer(
{
key: fs.readFileSync("/etc/letsencrypt/live/shafirpl.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/shafirpl.com/fullchain.pem"),
},
app
);
httpsServer.listen(443, () => {
console.log("HTTPS Server running on port 443");
});
而在我的axios.post中,我是这样使用的
const url = "https://shafirpl.com:443/email";
const sendMessage = async () => {
const config = {
headers: {
'Content-Type': 'application/json',
}
}
const body = JSON.stringify({ name, email, company, message });
try {
const res = await axios.post(url, body, config);
console.log(res);
clearForm();
showSuccessMessage();
} catch (error) {
console.log(error);
showFailureMessage();
}
}
const showFailureMessage = () => {
setFailureAlert(true);
setTimeout(() => {
setFailureAlert(false)
}, 3000);
}
但是现在我又遇到了这个错误: 对“https://shafirpl.com/email' from origin 'https://www.shafirpl.com”处的 XMLHttpRequest 的访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在 'Access-Control-Allow-Origin' header。
我实际上不知道如何解决这个问题,因为我对整个 MERN 堆栈构建还很陌生。谁能帮我这个?我只想使用 axios
发送电子邮件我有同样的问题 - 我做了什么,我从服务器和客户端删除了显式端口。然后我注意到我正在点击 http://mydomain.... please try accessing it from https://mydomain...这对我有用 :) 希望对您有所帮助!
我想我已经解决了这个问题。我决定通过我的 node.js 应用程序来提供我的 React 构建,而不是 运行 2 个不同的应用程序。我的做法是这样的:
const express = require("express");
// const connectDB = require("./config/db");
const path = require("path");
// routes variables
const emailRoute = require("./routes/email");
const resumeRoute = require("./routes/resume");
const app = express();
app.use(express.json({ extended: false }));
app.use("/api/email", emailRoute);
app.use("/api/resume", resumeRoute);
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
app.listen(80);
然后根据我的 axios 请求,我就这样做了:
const url = "/api/email"; const sendMessage = async () => {
const config = {
headers: {
'Content-Type': 'application/json',
}
}
const body = JSON.stringify({ name, email, company, message });
try {
const res = await axios.post(url, body, config);
console.log(res);
clearForm();
showSuccessMessage();
} catch (error) {
console.log(error);
showFailureMessage();
}
}
目前一切正常。 对于发送文件下载的简历,我不得不使用 /api/resume 而不是 像这样
<Nav.Link eventKey="6" activeClassName="active-nav" href="https://shafirpl.com/api/resume" target="_blank" rel="noopener noreferrer">Resume</Nav.Link>
现在简历下载也正常 感谢大家的帮助