关于node.js:无法加载资源:服务器响应状态为405(不允许)需要nginx.conf的帮助

Failed to load resource: the server responded with a status of 405 (Not Allowed) needs help on nginx.conf

我有完整的Mern Stack应用程序和AXIOS。在我的本地主机上,这个应用程序工作得很好,但是当我在nginx上部署这个应用程序时,所有的post请求都被拒绝了。我尝试了很多在网上找到的解决方案,但都不起作用。我认为这是CORS问题/nginx配置问题。我把nginx.conf弄好了吗?我的节点在localhost:8000上运行,在localhost:3000上响应。

error message 405 not allowed

编辑

我尝试过的事情:

Nginx.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
    }

}

我在节点上也需要这个吗?

1
2
3
4
5
6
7
8
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();
});

节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
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;


您的nginx配置错误。对于要通过nginx公开的节点应用程序,您需要一个反向代理,我已经回答了一个相关的问题。

nginx配置用于不使用SSL的反向代理。服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
    }

}

使用SSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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;
    }
 }

example.com中,您将已注册的域名放在您的IP上。如果您没有域,可以通过在主机中添加它来测试它,如何将IP添加到主机名文件中

例子127.0.0.1 example.com

每当你看到http://localhost:3000;时,你就把内部节点应用的IP和端口放在那里。如果它与localhost:port在同一台计算机中,则将其保留为localhost:port。

编辑1

以你为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
    }

}

编辑2

对于nodemail来说,有两种方法可以工作,比如说,nodemailerlocalhost:3000端口运行,要么使用lovechangingworld.org:8088端口,要么创建mail.lovechangingworld.org之类的子域。在sites-availabletouch mail.lovechangingworld.org中创建文件2。添加配置

示例1新子域:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
        }

    }

示例2不同端口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 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应该是服务器名,您提供的是文档根目录。
  • 在服务器上运行节点应用程序,并在nginx配置中向节点应用程序提供一个reverse proxy。您可以使用此文档为生产设置nodejs应用程序