[英]Failed to load resource: the server responded with a status of 405 (Not Allowed) needs help on nginx.conf
I have full MERN stack app with AXIOS.我有 AXIOS 的完整 MERN 堆栈应用程序。 On my localhost, the app works perfectly but when I deploy the app on nginx, all the POST request gets denied.
在我的本地主机上,该应用程序运行良好,但是当我在 nginx 上部署该应用程序时,所有POST请求都被拒绝。 I tried many solutions that I found on the web but doesn't work.
我尝试了在网上找到的许多解决方案,但都不起作用。 I think it's CORS problem/ nginx config problem.
我认为这是 CORS 问题/ nginx 配置问题。 Did I make Nginx.conf right?
我做 Nginx.conf 对吗? My node is running on localhost:8000, React on localhost:3000.
我的节点在 localhost:8000 上运行,在 localhost:3000 上反应。
EDIT编辑
Things that I have tried:我尝试过的事情:
Nginx.conf: nginx.conf:
server {
listen 80;
server_name lovechangingtheworld.org;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Do I need this on node too?我在节点上也需要这个吗?
router.use((request, response, next) => {
response.header("Access-Control-Allow-Origin", "*");
response.header(
"Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
response.header("Access-Control-Allow-Headers", "Content-Type");
next();
});
node:节点:
const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const keys = require("../../config/keys");
const passport = require("passport");
// Load Input Validation
const validateRegisterInput = require("../../validation/register");
const validateLoginInput = require("../../validation/login");
// Load User model
const User = require("../../models/User");
router.use((request, response, next) => {
response.header("Access-Control-Allow-Origin", "*");
response.header(
"Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
response.header("Access-Control-Allow-Headers", "Content-Type");
next();
});
// @route GET api/users/test
// @desc Tests users route
// @access Public
router.get("/test", (req, res) => res.json({ msg: "Users Works" }));
// @route POST api/users/register
// @desc Register user
// @access Public
router.post("/register", (req, res) => {
console.log("333333333333333333333333", req.body);
const { errors, isValid } = validateRegisterInput(req.body);
// Check Validation
if (!isValid) {
return res.status(400).json(errors);
}
User.findOne({ email: req.body.email }).then(user => {
if (user) {
errors.email = "Email already exists";
return res.status(400).json(errors);
} else {
// const avatar = gravatar.url(req.body.email, {
// s: '200', // Size
// r: 'pg', // Rating
// d: 'mm' // Default
// });
const newUser = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => res.json(user))
.catch(err => console.log(err));
});
});
}
});
});
// @route GET api/users/login
// @desc Login User / Returning JWT Token
// @access Public
router.post("/login", (req, res) => {
const { errors, isValid } = validateLoginInput(req.body);
// Check Validation
if (!isValid) {
return res.status(400).json(errors);
}
const email = req.body.email;
const password = req.body.password;
// Find user by email
User.findOne({ email }).then(user => {
// Check for user
if (!user) {
errors.email = "User not found";
return res.status(404).json(errors);
}
// Check Password
bcrypt.compare(password, user.password).then(isMatch => {
if (isMatch) {
// User Matched
const payload = {
id: user.id,
name: user.name,
admin: user.adminLevel
}; // Create JWT Payload
// Sign Token
jwt.sign(
payload,
keys.secretOrKey,
{ expiresIn: 3600 },
(err, token) => {
res.json({
success: true,
token: "Bearer " + token
});
}
);
} else {
errors.password = "Password incorrect";
return res.status(400).json(errors);
}
});
});
});
// @route GET api/users
// @desc Get users
// @access Public
router.get("/", (req, res) => {
User.find({})
.sort({ date: -1 })
.then(users => {
console.log("get", users), res.json(users);
})
.catch(err => res.status(404).json({ nousersfound: "No users found" }));
});
// @route GET api/users/:id
// @desc Get eventful by id
// @access Public
router.get("/:id", (req, res) => {
User.findById(req.params.id)
.then(user => {
console.log(user), res.json(user);
})
.catch(err =>
res.status(404).json({ nouserfound: "No user found with that ID" })
);
});
// @route POST api/users/:id
// @desc change user to admin
// @access Private
router.post(
"/:id",
passport.authenticate("jwt", { session: false }),
(req, res) => {
User.findOne({ _id: req.params.id })
.then(user => {
console.log("1231231231", user);
if (user) {
if(user.adminLevel)
user.adminLevel = false;
else
user.adminLevel = true;
}
user.save().then(user => res.json(user));
})
.catch(err => res.status(404).json({ usernotfound: "No post found" }));
}
);
// @route GET api/users/current
// @desc Return current user
// @access Private
router.get(
"/current",
passport.authenticate("jwt", { session: false }),
(req, res) => {
res.json({
id: req.user.id,
name: req.user.name,
email: req.user.email,
admin: req.user.adminLevel
});
}
);
// @route DELETE api/users
// @desc Delete user
// @access Private
router.delete(
"/",
passport.authenticate("jwt", { session: false }),
(req, res) => {
console.log("at route", req.body);
User.findOneAndRemove({ _id: req.user.id }).then(() =>
res.json({ success: true })
);
}
);
module.exports = router;
The nginx configuration that you have is wrong.您拥有的 nginx 配置是错误的。 For node app to be exposed through nginx you need a Reverse Proxy I have already answered a related question
要通过 nginx 公开节点应用程序,您需要一个反向代理我已经回答了一个相关问题
nginx config for Reverse proxy using no SSL.不使用 SSL 的反向代理的 nginx 配置。 server.
服务器。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Using SSL使用 SSL
server {
listen 443;
server_name example.com;
ssl_certificate /etc/letsencrypt/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://localhost:3000;
proxy_read_timeout 90s;
proxy_redirect http://localhost:3000 https://example.com;
}
}
In the example.com
you put your domain that you have registered with the IP of your.在
example.com
您将使用您的 IP 注册的域放入。 If you dont have a domain you can test it by adding it in the hosts How to add an IP to hostname file如果您没有域,您可以通过在主机中添加它来测试它如何将 IP 添加到主机名文件
Example 127.0.0.1 example.com
示例
127.0.0.1 example.com
Where ever you see http://localhost:3000;
你在哪里看到
http://localhost:3000;
you put the IP and port of the internal node app.你把内部节点应用程序的IP和端口。 In case its in the same machine you leave it as localhost:port.
如果它在同一台机器上,您将其保留为 localhost:port。
EDIT 1编辑 1
In you case在你的情况下
server {
listen 80;
server_name lovechangingworld.org;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
EDIT 2编辑 2
For nodemailer to work there are two ways.Lets say that nodemailer
runs at port localhost:3000
Either use a port like lovechangingworld.org:8088
or create a subdomain like mail.lovechangingworld.org
.要让 nodemailer 工作,有两种方式。假设
nodemailer
在端口localhost:3000
运行,要么使用lovechangingworld.org:8088
类的端口,要么创建一个子域,如mail.lovechangingworld.org
。 Create file in sites-available
touch mail.lovechangingworld.org
2. Add the configuration在
sites-available
touch mail.lovechangingworld.org
创建文件 2. 添加配置
Example 1 new subdomain:示例 1 新子域:
server {
listen 80;
server_name mail.lovechangingworld.org;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Example 2 diferent port:示例2不同端口:
server {
listen 8088;
server_name lovechangingworld.org;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server_name
should be server name, you are providing document root instead. server_name
应该是服务器名称,您提供的是文档根目录。reverse proxy
in your Nginx conf to your node app.reverse proxy
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.