React & nginx 路由到子目录

cit*_*vin 12 nginx reactjs

刚开始使用 React。我创建了一个应用程序,create-react-app它应该运行一段sub-directory时间,同时对不同的路径进行 API 调用。

反应应用程序:

服务器上的位置: /var/www/myapp/build

端点: https://foo.example.com/analytics

数据 API 端点: https://foo.example.com/api/data

Nginx 设置

    location /analytics {
           root /var/www/myapp/build;
           try_files $uri /index.html;
    }
Run Code Online (Sandbox Code Playgroud)

"homepage":"https://foo.example.com/analytics"在客户端的 中设置时package.json,所有资源路径似乎都是正确的(即https://foo.example.com/analytics/static/...),但是在检查网络.../api/data时,我的浏览器的网络检查器中没有显示请求,并且应用程序没有正确生成。

App's API call(fetch('https://foo.example.com/api/data')而不是fetch('/api/data')) 中使用绝对路径似乎也无济于事。

而不是当我设置"homepage":"."package.json,改变它的Nginx的配置担任服务器的根目录,应用程序的作品反应build目录。

server {
        root /var/www/myapp/build;
}
Run Code Online (Sandbox Code Playgroud)

但是,在这种情况下,该应用程序也可以在 下使用https://foo.example.com,这是我不想要的。

我强烈怀疑这与路由有关,但无法弄清楚如何解决它。所以任何帮助将不胜感激!

--- 编辑/解决方案 ---

我怀疑这是最直接的解决方案,但以下设置对我有用:

反应应用

package.json"homepage":"./analytics"运行前设置npm run build

Nginx 配置:

    location =  /analytics {

            root /var/www/myapp/build;
            try_files /index.html =404;
    }

    location ~ ^/analytics(.*) {

            root /var/www/myapp/build;
            try_files $1 $1/ /index.html =404;
    }
Run Code Online (Sandbox Code Playgroud)

我的理解是,使用的初始设置try_files $uri是在根目录中/var/www/myapp/build查找完整 uri 的文件,而不仅仅是后面的路径/analytics。例如,当请求../analytics/css/styles.css它时,它会检查一个文件(或目录)是否可用,/var/www/mayapp/build/analytics/css/styles.css而其下不存在,因此它继续index.html作为后备服务。因此,正则表达式解决方法。

不过,改进此解决方案的反馈仍然非常受欢迎。

Jua*_*cía 20

我正在努力解决同样的问题。最后,我能够使用官方文档和答案组合解决它:

假设:

  • 您的 React 应用程序基于create-react-app包(您正在使用react-router-dom)。
  • 您正在使用 Nginx 并且根路径正被另一个服务(甚至是另一个 React/Gatsby 应用程序,这是我的情况)使用。
  • 您希望在子目录中部署 React App,并能够从该子目录提供 React App 的所有静态数据。

反应应用程序更改

基于官方文档

  1. 更新您BrowserRouter的加入basename。例子:<BrowserRouter history={history} basename="/webapp">
  2. 指定homepage你的package.json。例子:"homepage": "/webapp"
  3. 如果您通过相对路径引用静态文件,则应将子目录添加到该引用中。例子:src="/static/logo/logo.png"变成src="/webapp/static/logo/logo.png".

Nginx 变化

location ^~ /webapp {
   alias /var/www/myapp/build;
   try_files $uri $uri/ /webapp/index.html;
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您提供这个分步解决方案。如果有人想知道:您不需要使用路由器的任何内容,只需将 &lt;BrowserRouter basename="/webapp"&gt; 添加到您的根应用程序就足够了。 (5认同)
  • 不是所有的英雄穿着斗篷... (2认同)

小智 5

以下是 nginx 位置配置的示例:

\n\n
location ^~ /analytics  {\n    alias /var/www/myapp/build;\n\n    subs_filter href="/ href="http://foo.example.com/analytics;\n    subs_filter src="/ src="http://foo.example.com/analytics;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  • 设置location为,意味着在位置大括号中创建的规则将在有人访问http://foo.example.com/analytics^~ /analytics时生效
  • \n
  • 设置alias为 create-react-app site 的静态构建文件夹/var/www/myapp/build。当访问者点击您的子目录 url foo.example.com/analytics 时,将提供 \xe2\x80\x99 服务
  • \n
  • 接下来,这两行将以新的完整 URLsubs_filter替换对 React app\xe2\x80\x99s 主目录开头的任何引用href和url。这将确保 NGINX 正确定位并提供您的所有 CSS 和 JS 文件。src/
  • \n
\n\n

最后一件事,在 Create-React-App 的情况下,createBrowserHistory您的 React 路由器中的任何引用都需要替换为createHashHistory,因为浏览器历史记录不会\xe2\x80\x99 无法与上述 NGINX 配置一起使用。

\n