Rails 控制器到 return 整个 React 应用程序

Rails controller to return a whole react app

我有一个 Rails API 应用程序和一个单独的独立 React 应用程序。

我想创建一个控制器,returns 将整个应用程序提供给最终用户,让 React 应用程序使用来自专用控制器的 API,而不是创建两个服务器。

如何巧妙地做到这一点?

React 应用树是:

我无法直接写出如何连接它们,这会有点冗长,但这里有一个 link 可以帮助您:

  1. 这篇 link 讨论了 'create-react-app' 这是您创建 React 应用程序所做的,并且 Rails API.

https://www.fullstackreact.com/articles/how-to-get-create-react-app-to-work-with-your-rails-api/

一般来说,您所做的就是创建 'Rails API' 应用程序并使用您的控制器渲染 json,然后使用 React fetch/axios 连接到您的 Rails API

在这方面不是很有经验,但如果有帮助的话,这是我在最近的项目中所做的:

  • 使用/集成webpacker gem到您的Rails项目

  • app/config/routes.rb:

    # all JSON requests goes here
    scope constraints: -> (request) { request.format == :json } do
      # all of your Rails API routes goes here
    end
    
    # all HTML requests goes here,
    # as your react-router should already be able to handle this
    scope constraints: -> (request) { request.format == :html } do
      # this matches ALL paths to bootstrapper action
      match '*path', to: 'application#bootstrapper'
    end
    
    root 'application#boostrapper'
    
  • app/controllers/application_controller.rb:

    def bootstrapper
      render template: 'layouts/bootstrapper'
    end
    
  • app/views/layouts/bootstrapper.html.erb

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <!-- YOUR USUAL <head> HERE -->
        <%= stylesheet_link_tag    "application" %>
        <%= javascript_include_tag "application" %>
        <%= csrf_meta_tags %>
      </head>
      <body>
        <!-- DONT NEED THE <%= yield %> HERE -->
        <%= javascript_pack_tag 'your_react_pack' %>
        <%= stylesheet_pack_tag 'your_react_pack' %>
      </body>
    </html>
    
  • 最后配置你的 app/javascript/packs/your_react_pack.js(这是你的 React 文件的 entry-point,所以你会 import 你的 React 应用程序)请参阅 webpacker 了解详细信息

奖金

  • Cross-Site 请求伪造 (CSRF) 保护是必须的!在 Rails 5(或者也许还有 4?)中,您可以简单地使用 Rails.csrfToken() 在 JS 中获取令牌,并在提交时将其作为 'X-CSRF-Token' header 传递 JSON 请求到您的 Rails 应用。确保你的 app/assets/javascripts/application.js 中有 //= require rails-ujs 以便你能够使用 Rails.csrfToken()