跳转到主要内容

前端开发常见坑处理

各种环境需要的地址类的处理

  • .env 文件
# 新建
# .env.development 、 .env.production 、 .env.test

# 主站API地址
VITE_APP_API=/api

# 文件服务地址
VITE_FILE_API=/oss/file

  • 环境变量读取工具类

/**
 * 获取环境变量
 */
export const getEnvByKey = (key: string) => {
  const val = window.SITE_CONFIG?.[key] || import.meta.env[key];
  if (val) {
    return val;
  } else {
    console.warn(SITE_CONFIG);
    throw new Error("未找到环境变量");
  }
};

  • nginx 运时时外部修改
#!/bin/bash

cat > /usr/share/nginx/html/env.js <<EOF
window.SITE_CONFIG = {
    VITE_APP_API: "${VITE_APP_API:-/api}",
    VITE_FILE_API: "${VITE_FILE_API:-https://smart.saas.vppark.cn/file}",
    VITE_VISITOR_URL: "${VITE_VISITOR_URL:-https://smart-home.saas.vppark.cn/h5}"
};
EOF

cp -r /tmp/icon/* /home/upload_file

nginx -g 'daemon off;'

  • index.html
    <script src="./env.js"></script>

    <script>
      //全局钩子
      window.SITE_CONFIG = {
        //api
        apiURL: "<%=apiURL%>",
        ...window.SITE_CONFIG
      };
    </script>

内网图片、协议不一致处理

https不能调用http,后端返回的内网图片不能正常显示,开发环境https证书错误无法加载

1、修改代码处理图片路径走内网代理
/** 内网 / 第三方图片走同源反代,避免混合内容与跨域问题 */
export const INTRANET_IMAGE_PROXY_PREFIX = "/intranet-image-proxy";

/**
 * 与 nginx default.conf 的 intranet-image-proxy location 正则保持一致:
 * host 必须是 10.x.x.x / 172.x.x.x / 192.x.x.x(可带端口)。
 * nginx 只放行这三段,这里不匹配就走原地址,避免拼出 nginx 404 的代理路径。
 */
const INTRANET_HOST_PATTERN = /^(?:10|172|192)\.\d+\.\d+\.\d+(?::\d+)?$/;

/**
 * 内网 IP 的 http(s) 全路径图片包一层 /intranet-image-proxy/;
 * 其余(空值、相对路径、外网地址)原样返回。
 */
export function toInternetImage(src: string) {
  // 空、null、undefined、纯空白:返回空串
  const raw = String(src ?? "").trim();
  if (!raw) {
    return raw;
  }

  // 协议相对地址(//10.1.2.3:6120/a.jpg)补全 http:
  let url = raw;
  if (url.startsWith("//")) {
    url = `http:${url}`;
  }

  // 相对路径或其他协议不是全路径,不处理
  if (!/^https?:\/\//i.test(url)) {
    return raw;
  }

  // host 不是 10/172/192 段的内网 IP 不处理,规则与 nginx 放行一致
  const host = new URL(url).host;
  if (!INTRANET_HOST_PATTERN.test(host)) {
    return raw;
  }

  // 内网全路径:包一层同源代理,规避混合内容拦截
  return `${location.origin}${INTRANET_IMAGE_PROXY_PREFIX}/${url}`;
}


2、增加nginx图片代理配置
# 顶层区块

map $http_x_forwarded_proto $origin_scheme {
    default $http_x_forwarded_proto;
    ""      $scheme;
}

# 加在 server 区块下
    merge_slashes off;

    # 内网图片代理(设备抓拍等内网 http/https 图片统一走这里,proxy_redirect 改写 301 保持同源)
    location ~ ^/intranet-image-proxy/(?<upstream_scheme>https?)://(?<upstream_host>(10|172|192)\.\d+\.\d+\.\d+(?::\d+)?)(?<upstream_path>/.*)$ {
        proxy_pass $upstream_scheme://$upstream_host$upstream_path$is_args$args;
        proxy_set_header Host $upstream_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_ssl_verify off;

        # 处理上有游返回的重定向,避免跳转到内网地址
        proxy_redirect ~^(?<redirect_scheme>https?)://(?<redirect_host>(?:10|172|192)\.\d+\.\d+\.\d+(?::\d+)?)(?<redirect_path>/.*)$ $origin_scheme://$http_host/intranet-image-proxy/$redirect_scheme://$redirect_host$redirect_path;
    }