前端开发常见坑处理
各种环境需要的地址类的处理
- .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;
}