CORS OPTIONS request to POST XMLHttpRequest fails preflight incorrectly

Good Evening all, apologies if I’ve missed anything out or if I need to clarify anything or do something differently; it’s my first post. However, I am in need of your help.

At this time, I’m creating a .js client-side script on a front-end website that sends data from a form in application/json form as a POST request to a backend API. This code is written as creating an XMLHttpRequest through JS, setting the Content-Type header to application/json, and sending the data with a json payload as a POST request to /app of my API. What I see in the Chrome console is that the preflight OPTIONS request fails due to no Access-Control-Allow-Origin header is not passed in return. The response appears to be a Cloudflare response of Status 405. This is strange, however, as my API also utilises GET requests for certain autofill situations in the form which run perfectly. I’ve provided a screenshot below of the preflight request.

Preflight

The server that serves both domains (api. / www.) is nginx. The configuration is as follows for the API:

server {
        listen 443 ssl http2;
        server_name api.naxxxxe.net;
        access_log /var/log/nginx/api-naxxxxe.app-access.log;
        error_log /var/log/nginx/api-naxxxxe.app-error.log error;
        ssl_certificate /var/ssl/fullchain.pem;
        ssl_certificate_key /var/ssl/privkey.pem;
        add_header Allow 'GET, POST';
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header Referrer-Policy strict-origin;
        add_header Access-Control-Allow-Origin https://naxxxxe.net;
        add_header Access-Control-Allow-Methods 'GET, POST';
        add_header Access-Control-Allow-Headers Content-Type;
        location / {
                proxy_pass http://127.0.0.1:1337;
                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;
        }
        location /app {
                add_header Access-Control-Allow-Origin https://naxxxxe.net;
        }
}

The backend software behind the API is a PM2 Daemonised Node.js Express program.

As clearly stated, my server is fully configured to accept the request. This is also proven by a multitude of tests using Postman with the same parameters which were all successful.

Bottom line is that my API is fully operational code-wise and has been tested functionally with Postman. With respect to the web portion; GET requests work fine, but POST requests fail due to CORS. I assume this is some incredibly easy fix that I’ve missed in the Nginx configuration; however, I have exhausted all of my knowledge on the matter, and I’m turning towards you all to assist me.

Thanks again to you all for reading through this and showing interest in helping me. Again, apologies if I’ve missed anything out or if I’ve not properly written this topic. Please reply below and I’ll gladly answer when I can.

Does it go to api.naxxxxe.net or www.api.naxxxxe.net?

GET and POST, but how about HEAD?

What happens if you make a change like add_header Access-Control-Allow-Origin https://naxxxxe.net; just insude the server{} block, not being in location{} block as it is now?

  • at first sight, meaning the server is already being as a sub-domain api, so the Access-Control-Allow-Origin should be inside server, and not just /app?

Shuldn’t it be strict-origin-when-cross-origin because you pass the request to the sub-domain while being inside the same origin/domain?

Those fixes seemed to do the trick. I took out my feeble attempt at a fix with the location block with the …Allow-Origin header, added HEAD to the Allow header, and changed the referrer-policy header to strict-origin-when-cross-origin. Just to clarify your first question, however, everything excludes www except the root part of the domain. Thank you very much @fritexvz for your help. I’ll leave the final config below:

server {
        listen 443 ssl http2;
        server_name api.naxxxxe.net;
        access_log /var/log/nginx/api-naxxxxe.app-access.log;
        error_log /var/log/nginx/api-naxxxxe.app-error.log error;
        ssl_certificate /var/ssl/fullchain.pem;
        ssl_certificate_key /var/ssl/privkey.pem;
        add_header Allow 'GET, POST, HEAD';
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header Referrer-Policy strict-origin-when-cross-origin;
        add_header Access-Control-Allow-Origin https://naxxxxe.net;
        add_header Access-Control-Allow-Methods 'GET, POST';
        add_header Access-Control-Allow-Headers Content-Type;
        location / {
                proxy_pass http://127.0.0.1:1337;
                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 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.