POST request not allowed - 405 Not Allowed - nginx, even with headers included

node.jsExpressNginxCross DomainNodemailer

node.js Problem Overview


I have a problem in trying to do a POST request in my application and I searched a lot, but I did not find the solution.

So, I have a nodeJS application and a website, and I am trying to do a POST request using a form from this site, but I always end up in this:

enter image description here

and in the console I see :

    Uncaught TypeError: Cannot read property 'value' of null 
Post "http://name.github.io/APP-example/file.html " not allowed

that is in this line of code :

file.html:

<form id="add_Emails" method ="POST" action="">
    
    <textarea rows="5" cols="50" name="email">Put the emails here...
    </textarea>
        
        <p>
        <INPUT type="submit" onclick="sendInvitation()" name='sendInvitationButton' value ='Send Invitation'/>
        </p>
            
            
</form>

<script src="scripts/file.js"></script>

file.js:

function sendInvitation(){
  
    var teammateEmail= document.getElementById("email").value;

I read many post and a documentation of cross domain but it did not work. research source 1:http://enable-cors.org/server.html research source 2: http://www.w3.org/TR/2013/CR-cors-20130129/#http-access-control-max-age

What I am doing now:

I am trying to POST from a different domain of my server :

POST REQUEST : http://name.github.io/APP-example/file.html , github repository

POST LISTENER : "http://xxx.xxx.x.xx:9000/email , server localhost ( x-> my ip address)

So, I had the same problem in other files, but I fixed it putting this code in the begginning of each route:

var express = require('express');
var sha1 = require('sha1'); 

var router = express.Router(); 
var sessionOBJ = require('./session');

var teams = {} 
var teamPlayers = []

router.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header("Access-Control-Allow-Methods", "PUT, GET,POST");
  next();
 });

and I fixed it doing it.

Now, I am having the same problem, but in this file the only difference is that I deal with SMTP and emails, so I post an email and send an Email to this email I received in the POST request.

THe code is working totally fine with POSTMAN, so, when I test with POSTMAN it works and I can post.

I included this code below instead of the first one I showed but it did not work as well:

router.all('*', function(req, res, next){
            res.header("Access-Control-Allow-Origin", "*")
            res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
            res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept")
            res.header("Access-Control-Max-Age", "1728000")
            next();
        });

Does someone know how to solve it?

Thank you.

node.js Solutions


Solution 1 - node.js

This configuration to your nginx.conf should help you.

https://gist.github.com/baskaran-md/e46cc25ccfac83f153bb

server {
    listen       80;
    server_name  localhost;

    location / {
        root   html;
        index  index.html index.htm;
    }

    error_page  404     /404.html;
    error_page  403     /403.html;
    
    # To allow POST on static pages
    error_page  405     =200 $uri;
    
    # ...
}

Solution 2 - node.js

This is the real proxy redirection to the intended server.

server {
  listen          80;
  server_name     localhost;
location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
    proxy_pass http://xx.xxx.xxx.xxx/;
    proxy_redirect off;
    proxy_set_header Host $host;

  }
}

Solution 3 - node.js

I noticed this wasn't working with a static-first-then-reverse-proxy setup. Here's what that looks like:

location @app {
  proxy_pass http://localhost:3000$request_uri;
}
    
location / {
  try_files $uri $uri/ @app;
  error_page 405 @app;
}

Solution 4 - node.js

In my case it was POST submission of a json to be processed and get a return value. I cross checked logs of my app server with and without nginx. What i got was my location was not getting appended to proxy_pass url and the version of HTTP protocol version is different.

  • Without nginx: "POST /xxQuery HTTP/1.1" 200 -
  • With nginx: "POST / HTTP/1.0" 405 -

My earlier location block was

location /xxQuery {
    proxy_method POST;
    proxy_pass http://127.0.0.1:xx00/;
    client_max_body_size 10M;
}

I changed it to

location /xxQuery {
    proxy_method POST;
    proxy_http_version 1.1;
    proxy_pass http://127.0.0.1:xx00/xxQuery;
    client_max_body_size 10M;
}

It worked.

Solution 5 - node.js

I have tried the solution which redirects 405 to 200, and in production environment(in my case, it's Google Load Balancing with Nginx Docker container), this hack causes some 502 errors(Google Load Balancing error code: backend_early_response_with_non_error_status).

In the end, I have made this work properly by replacing Nginx with OpenResty which is completely compatible with Nginx and have more plugins.

With ngx_coolkit, Now Nginx(OpenResty) could serve static files with POST request properly, here is the config file in my case:

server {
  listen 80;
    
  location / {
    override_method GET;
    proxy_pass http://127.0.0.1:8080;
  }
}

server {
  listen 8080;
  location / {
    root /var/www/web-static;
    index index.html;
    add_header Cache-Control no-cache;
  }
}

In the above config, I use override_method offered by ngx_coolkit to override the HTTP Method to GET.

Solution 6 - node.js

I had similiar issue but only with Chrome, Firefox was working. I noticed that Chrome was adding an Origin parameter in the header request.

So in my nginx.conf I added the parameter to avoid it under location/ block

proxy_set_header Origin "";

Solution 7 - node.js

I had a similar issue with VueJs as the frontend app hosted at example.com with my Rails app as API hosted at api.example.com. Vue was configured to fetch data via an ENV variable VUE_APP_API_BASE_URL.

I made a rookie mistake of forgetting to create env.production.local on the production server hence when building the VueJs app the url was never picked up. All request were therefore being routed to e.g example.com/signin instead of api.example.com/signin and thus the error.

Upon creating the file on the production server and adding the variable, then building the vuejs app afresh everything worked fine!

Solution 8 - node.js

It's too late but if anyone has this problem, add the below code in nginx.conf

server {

        ...

        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
                # With php-cgi (or other tcp sockets):

        }


}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndBecaPineView Question on Stackoverflow
Solution 1 - node.jsBaskarView Answer on Stackoverflow
Solution 2 - node.jsIndra UpradeView Answer on Stackoverflow
Solution 3 - node.jsWilliam CasarinView Answer on Stackoverflow
Solution 4 - node.jsjasoosView Answer on Stackoverflow
Solution 5 - node.jsSiyuan ZhangView Answer on Stackoverflow
Solution 6 - node.jsSCGView Answer on Stackoverflow
Solution 7 - node.jsJoseph N.View Answer on Stackoverflow
Solution 8 - node.jsHamidReza RTMView Answer on Stackoverflow