Kevin T.
Kevin T.

Reputation: 758

405 error with no message on POST request and the Request URL has the :path appended to it

I am running an nginx webserver to serve my app and between my frontend and express backend I have an nginx reverse proxy. I get the 405 error with no message when I click the stripe pay now button to submit. Looking at devtools reveals the following, the request url is grossly incorrect:

devtools screenshot

405 POST error

Why is the request url appending the url a second time? On the client I have axios configured as such:

const apiClient = axios.create({
  baseURL: "goldcoastcookiecompany.com", // http://localhost:5000
  withCredentials: true,
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json",
    "Referrer-Policy": "no-referrer-when-downgrade",
    "Access-Control-Allow-Origin": "goldcoastcookiecompany.com", // http://localhost:8080
    "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS"
 }

});

On the backend, express cors middleware:

app.use(cors({ credentials: true, origin: 'goldcoastcookiecompany.com' })) // http://localhost:8080 in dev

The route:

router
  .route('/create-payment-intent')
  .post(express.json(), OrdersController.apiCreatePaymentIntent)

The Nginx webserver config:

#### HTTP - redirect all traffic to HTTPS
server {
  listen 80;
  listen [::]:80 default_server ipv6only=on;
  return 301 https://$host$request_uri;
}

#### HTTPS - proxy all requests to Node app 
server {
  #ENABLE HTTP/2 
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name goldcoastcookiecompany.com;

#### USE LETSENCRYPT CERTIFICATES
  ssl_certificate ....
  ssl_certificate_key ....

#### INCLUDE THE SSL CONFIGURATION FROM CIPHERLI.ST
   include snippets/ssl-params.conf;

  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_set_header Host $host;
    proxy_pass http://localhost:8080;
    proxy_ssl_session_reuse off;
    proxy_cache_bypass $http_upgrade;
    proxy_redirect off;
  }
}

and the nginx reverse proxy:

server {
  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-Forwared-Proto $scheme;
  proxy_pass http://localhost:5000;
}

}

This does not appear to be CORS issue, how and why is the :path added to what the request url that should be https://goldcoastcookiecompany.com/create-payment-intent. From what Iv've read this is a backend issue not necessarily a frontend one. Most of what I gooled is about 405 method not found or cors, but nothing about 405 with no error message.

Upvotes: 1

Views: 1049

Answers (1)

Cagri
Cagri

Reputation: 366

When you set baseURL: "goldcoastcookiecompany.com", and browser URL is https://goldcoastcookiecompany.com/ , by axios, request URL becomes goldcoastcookiecompany.com/create-payment-intent but this isn't a valid URL because it doesn't have the protocol. It's only a path.
Then, when axios sends that request with XHR or ajax, browser sees there is no protocol, it's not an URL, and assumes you want to submit the request relative to the address you're currently on, then adds your current window URL to beginning of that, and you get windowURL+baseURL+requestPath which is https://goldcoastcookiecompany.com/goldcoastcookiecompany.com/create-payment-intent

Long story short:

  baseURL: "https://goldcoastcookiecompany.com/",


Or if you want it to be relative to the domain:

  baseURL: "/",

When on https://example.com/asd/asd/ and requesting test.html , final URL becomes https://example.com/test.html

Edit: Turns out, it's a problem on nginx configuration. He was serving frontend with the first nginx config, which forwards everything to the frontend, and no way to forward to nodejs backend server. So it was POSTing to frontend. Instead, we added this location block:

location /api/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:5000/;
} 

and on client, changed the API URLs accordingly. We did this so nginx can understand if request should be proxied to frontend or backend server.

Upvotes: 1

Related Questions