You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Nginx Ingress基于路径路由为服务提供静态文件?

解决前端服务部署在Nginx Ingress子路径下的静态资源路径问题

针对前端服务部署在example.com/front1这类子路径下,静态资源用绝对根路径(如href="/styles.css")导致404的问题,以下是几种无需修改前端源码的可行方案:

方案1:利用NJS动态改写请求路径(推荐)

这个方案通过Nginx的NJS模块,根据请求的Referer头判断请求所属的子服务,自动将根路径资源请求重写到对应子路径下,能覆盖动态JS生成的请求。

配置步骤:

  1. 创建NJS脚本ConfigMap

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-njs-scripts
      namespace: ingress-nginx
    data:
      path_rewrite.js: |
        function getBasePath(r) {
          const referer = r.headersIn['Referer'];
          if (!referer) return '';
          // 从Referer中提取子路径前缀(如从http://example.com/front1/page提取/front1)
          const url = new URL(referer);
          const pathSegments = url.pathname.split('/');
          if (pathSegments.length >= 2 && pathSegments[1]) {
            return '/' + pathSegments[1];
          }
          return '';
        }
    
  2. 修改Ingress Controller Deployment挂载ConfigMap
    找到Ingress Controller的Deployment(通常在ingress-nginx命名空间),添加Volume和VolumeMount:

    spec:
      template:
        spec:
          volumes:
          - name: njs-scripts
            configMap:
              name: nginx-njs-scripts
          containers:
          - name: controller
            volumeMounts:
            - name: njs-scripts
              mountPath: /etc/nginx/conf.d/
              readOnly: true
    
  3. 在目标服务的Ingress中注入Server Snippet

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: front1-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$1
        nginx.ingress.kubernetes.io/server-snippet: |
          js_import /etc/nginx/conf.d/path_rewrite.js;
          js_set $base_path path_rewrite.getBasePath;
          # 仅对根路径开头的请求进行改写,避免影响子路径下的正常请求
          if ($base_path != '' && $request_uri ~ ^/[^/]+) {
            rewrite ^/(.*)$ $base_path/$1 break;
          }
    spec:
      rules:
      - host: example.com
        http:
          paths:
          - path: /front1/?(.*)
            pathType: Prefix
            backend:
              service:
                name: front1-service
                port:
                  number: 80
    

优缺点:

  • 优点:无需修改响应体,能处理动态JS生成的资源请求,适配所有第三方前端服务
  • 缺点:依赖Referer头,若用户直接访问根路径资源URL(如example.com/styles.css)会失效,但这类场景极少

方案2:基于Referer的Nginx条件重写(轻量版)

如果不想折腾NJS,可以直接用Nginx的原生指令实现类似逻辑,配置更简单:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: front1-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/server-snippet: |
      # 匹配Referer中的子路径前缀,并重写请求路径
      if ($http_referer ~* "^https?://example.com/([^/]+)/") {
        set $service_prefix /$1;
        rewrite ^/(.*)$ $service_prefix/$1 last;
      }
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /front1/?(.*)
        pathType: Prefix
        backend:
          service:
            name: front1-service
            port:
              number: 80

优缺点:

  • 优点:无需额外挂载脚本,配置快速
  • 缺点:正则匹配能力有限,不适用于多层子路径的场景

方案3:Proxy Redirect结合Sub Filter(适配静态页面)

如果服务以静态页面为主,动态生成内容较少,可以结合proxy_redirect和sub_filter注解,同时修改响应头和响应体中的绝对路径:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: front1-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/proxy-redirect: "http://example.com/ http://example.com/front1/"
    nginx.ingress.kubernetes.io/proxy-redirect: "https://example.com/ https://example.com/front1/"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      sub_filter 'href="/' 'href="/front1/';
      sub_filter 'src="/' 'src="/front1/';
      sub_filter_once off;
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /front1/?(.*)
        pathType: Prefix
        backend:
          service:
            name: front1-service
            port:
              number: 80

优缺点:

  • 优点:能覆盖静态页面中的所有绝对路径引用
  • 缺点:对动态JS生成的路径无效,因为Sub Filter只处理初始响应体

方案4:兜底精确路径代理

如果上述方案都无法满足,且服务的静态资源路径固定,可以为每个资源单独配置Ingress规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: front1-resources-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /styles.css
        pathType: Exact
        backend:
          service:
            name: front1-service
            port:
              number: 80
      - path: /app.js
        pathType: Exact
        backend:
          service:
            name: front1-service
            port:
              number: 80
      # 继续添加其他静态资源路径

优缺点:

  • 优点:配置简单,无需复杂逻辑
  • 缺点:需要维护大量精确路径规则,仅适用于资源数量少的服务

内容的提问来源于stack exchange,提问作者Emanuel Kozerski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:40:30