使用 Next.js 和 Headless Wordpress 作为后端的 CORS 问题

Posted

技术标签:

【中文标题】使用 Next.js 和 Headless Wordpress 作为后端的 CORS 问题【英文标题】:CORS problem using Next.js with Headless Wordpress as a backend 【发布时间】:2019-10-26 09:45:57 【问题描述】:

我正在使用 next.js 作为我的前端框架和 wordpress rest api 作为我的后端来创建应用程序。要使用 WPAPI 库从 wp-rest-api im 获取路由,并且在 localhost 环境中没有任何问题,但是当我上传我的应用程序以在生产服务器(VPS 机器)上显示时,它因 CORS 错误而发疯,我可以' t 从我的后端获取任何东西,因为我得到错误: error

这是我网站的链接:frontend

我已经尝试过:在我的 wordpress 主题中添加一个 cors 标题(我正在使用主题作为我的函数,而这些函数还没有在 REST api 中)

这是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
);
在前端的 server.js 中添加一个 cors 库 为标头管理添加插件

不幸的是,没有任何效果。

这是我的 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);
  );

cors 被阻止的端点的预期输出应如下所示: expected output

【问题讨论】:

响应的 HTTP 状态码是什么?您可以使用浏览器开发工具中的网络窗格进行检查。是 4xx 还是 5xx 错误,而不是 200 OK 成功响应? 我用前端添加了一个指向我的网站的链接 - 如果你能看一下,因为我在这条路线上只看到 301 代码,然后中止 好的,所以我自己尝试了http://igorszostek.pl:3000/,但我无法重现错误。具体来说,我看到前端 javascript 代码正在向 https://igorszostek.pl/projekty/codevly2/wordpress/wp-json/menus/v1/locations/header-menu 发出一个跨域 XHR 请求,它得到了一个 200 OK 响应,其中包含所有正确的 CORS Access-Control-Allow-\* 标头。我在 Chrome、Firefox 和 Safari 中进行了尝试,其中任何一个都没有出现 CORS 错误。 (我看到的唯一错误是Error: Invalid value for <svg> attribute height="auto"。) 您是否在其他浏览器中尝试过该网站?您是否尝试过清除网站的浏览器缓存,或强制重新加载?鉴于无法重现 CORS 错误,问题可能是:您的浏览器正在加载文档的先前缓存版本——在您在后端添加 CORS 响应标头之前浏览器缓存的版本。我想你也有可能有一个干扰的浏览器扩展。 【参考方案1】:

尝试在应用声明后添加app.use(cors());

这会通过 cors 模块路由所有请求,因此它可以修复您的标头。功能可能不同于 server.use(cors());

【讨论】:

如果有人想了解更多信息,请参阅Next documentation 和此micro-cors readme【参考方案2】:

看起来您的服务器(不是 wordpress)不允许 CORS - 所以请更改您的生产服务器设置 - here 是 nginx 和 appache 的示例 CORS 配置。

【讨论】:

【参考方案3】:

我发现出了什么问题,所以为了后代:

我的前端在端口 3000 上,在 HTTP 上 我的 Wordpress 在端口 80 上,在 HTTPS 上

但我从前端通过 HTTP 向 wordpress 发出请求,导致重定向前端->wp/http->wp/https,因此,cors 标头在此过程中丢失。

愚蠢的错误,在配置中添加了一个字母,一切正常:)

【讨论】:

以上是关于使用 Next.js 和 Headless Wordpress 作为后端的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

Word转PDF

弃用警告:在 Python 中使用 Geckodriver 和 Selenium 将 setter 用于无头属性而不是 set_headless opts.set_headless(headless=

如何组合和使用多个 Next.js 插件

如何使用几个 next.js 插件(打字稿和手写笔)

Next.js/Next-Auth/Apollo/GraphQL 设置

next.js中重复的CSS和Js渲染问题