0

I'm creating app using next.js as my frontend framework and wordpress rest api as my backend. To fetch routes from wp-rest-api im using WPAPI library, and in localhost enviroment there weren't any problems, but when i uploaded my app to show on production server (VPS machine) it went nuts with CORS errors, i can't fetch anything from my backend, as i get error: error

Here is link to my site: frontend

I already tried: adding a cors headers inside my wordpress theme (i'm using theme as my functions that are not already in REST api)

Here is code in functions.php:

add_action(
    'rest_api_init',
    function () {
        remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );

        add_filter(
            'rest_pre_serve_request',
            function ( $value ) {
                header( 'Access-Control-Allow-Origin: *' );
                header( 'Access-Control-Allow-Methods: GET,PUT,POST,DELETE,PATCH,OPTIONS' );
                header( 'Access-Control-Allow-Credentials: true' );
                header( 'Access-Control-Allow-Headers: Access-Control-Allow-Headers, Authorization, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers' );
                return $value;
            }
        );
    },
    15
);
  • Adding a cors library to my server.js inside frontend
  • Adding a plugin for header management

Nothing worked, unfortunately.

Here is my server.js


const express = require('express');
const next = require('next');
const cors = require('cors')

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();


app
  .prepare()
  .then(() => {
    const server = express();

    server.use(cors());

    server.options('*', cors())

    server.get("/blog", (req, res) => {
      app.render(req, res, "/blog/list");
    });

    server.get("/forum", (req, res) => {
      app.render(req, res, "/forum/list");
    });

    server.get("/:pageSlug", (req, res) => {
      const queryParams = { slug: req.params.pageSlug };
      app.render(req, res, "/page", queryParams);
    });

    server.get("/user/:action", (req, res) => {
      const queryParams = { action: req.params.action };
      app.render(req, res, "/user", queryParams);
    });

    server.get("/blog/:slug", (req, res) => {
      const queryParams = { slug: req.params.slug };
      app.render(req, res, "/blog/post", queryParams);
    });

    server.get("/forum/:id/:slug", (req, res) => {
      const queryParams = { slug: req.params.slug, id: req.params.id };
      app.render(req, res, "/forum/post", queryParams);
    });

    server.get("/:category/:postSlug", (req, res) => {
      const queryParams = { category: req.params.category, slug: req.params.postSlug };
      app.render(req, res, "/post", queryParams);
    });

    server.get('*', (req, res) => {
      return handle(req, res);
    });

    server.listen(3000, err => {
      if (err) throw err;
      console.log('> Ready on http://localhost:3000');
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

Expected output from endpoint that cors blocked should be like in this link: expected output

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Kizbo
  • 51
  • 2
  • 10
  • What’s the HTTP status code of the response? You can use the Network pane in browser devtools to check. Is it a 4xx or 5xx error rather than at 200 OK success response? – sideshowbarker Jun 12 '19 at 05:22
  • I added a link to my site with frontend - if you could look at that, because i see just 301 code on this route, then aborted – Kizbo Jun 12 '19 at 17:35
  • OK, so I tried `http://igorszostek.pl:3000/` myself, but I can’t reproduce the error. Specifically, I see that the frontend JavaScript code is making a cross-origin XHR request to `https://igorszostek.pl/projekty/codevly2/wordpress/wp-json/menus/v1/locations/header-menu` and it’s getting a 200 OK response with all the right CORS `Access-Control-Allow-\*` headers. I tried in Chrome, Firefox, and Safari, and there were no CORS errors in any of them. (The only error I see is a `Error: Invalid value for attribute height="auto"`.) – sideshowbarker Jun 12 '19 at 22:22
  • Have you tried the site in other browsers? Have you tried clearing your browser cache for the site, or force-reloading it? Given that the CORS error can’t be reproduced, it’s possible the problem is: your browser is loading a previously-cached version of the document — a version that the browser cached before you added the CORS response headers on the backend. I guess it’s also possible you could have a browser extension that’s interfering. – sideshowbarker Jun 12 '19 at 22:34

3 Answers3

2

I found out what was wrong, so for future generations:

My frontend was on port 3000, on HTTP My Wordpress was on port 80, on HTTPS

But i was making request to wordpress through HTTP from my frontend, that caused redirection frontend->wp/http->wp/https and because of that, cors headers were lost in the process.

Stupid mistake, one letter in configuration added and everything works as it should :)

Kizbo
  • 51
  • 2
  • 10
1

Try adding app.use(cors()); after app declaration.

This routes all requests through the cors module so it can fix your headers. Might function differently than server.use(cors());

Mikolaj Figurski
  • 133
  • 1
  • 2
  • 12
  • If anyone is looking for more info, see [Next documentation](https://nextjs.org/docs#api-middlewares) and this [micro-cors readme](https://github.com/possibilities/micro-cors/blob/8f150a817004bbae5db2b9f9fc27e437b86a68d5/README.md) – a.barbieri Dec 15 '19 at 15:37
-1

It looks like your server (not wordpress) not allow CORS - so change your production server settings - here are example CORS configurations for nginx and appache.

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345