nginx中间代理。前端下载资源跨域,太大不想放到服务端处理。

nginx中间代理。前端下载资源跨域,太大不想放到服务端处理。 一、检测nginx 是否支持luanginx -V | grep lua二、nginx的配置location /proxy/ { resolver 8.8.8.8 114.114.114.114 valid300s; resolver_timeout 10s; # 1. 用 Lua 解码 URL 参数 set_by_lua_block $target_url { local url ngx.var.arg_url if not url or url then return end -- 解码 URL处理 %3A %2F 等 local decoded ngx.unescape_uri(url) -- 验证是否是合法 URL if not decoded:match(^https?://) then return end return decoded } # 2. 参数验证 if ($target_url ) { return 400 {error:Missing or invalid url parameter}; } # 3. 可选白名单限制建议开启 if ($target_url !~ ^https?://([a-zA-Z0-9_-]\.)*coze\.cn(/|$)) { return 403 {error:Domain not allowed}; } # 4. 清除可能干扰的请求头 proxy_set_header Origin ; proxy_set_header Referer ; # 5. 模拟真实浏览器请求 proxy_set_header User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36; proxy_set_header Accept */*; proxy_set_header Accept-Language zh-CN,zh;q0.9,en;q0.8; # 6. 核心代理 proxy_pass $target_url; proxy_redirect off; proxy_set_header Host $proxy_host; # 7. SSL 配置 proxy_ssl_server_name on; proxy_ssl_protocols TLSv1.2 TLSv1.3; proxy_ssl_verify off; # 8. 视频流优化关闭缓冲 proxy_buffering off; proxy_request_buffering off; # 9. 不强制下载让浏览器根据 Content-Type 处理 # proxy_hide_header Content-Disposition; # add_header Content-Disposition attachment always; # 10. CORS 头 add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods GET, POST, OPTIONS always; add_header Access-Control-Allow-Headers * always; add_header Access-Control-Expose-Headers Content-Disposition, Content-Length always; # 11. 预检请求 if ($request_method OPTIONS) { return 204; } # 12. 超时设置 proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 60s; }三、vue示例// 代理请求工具函数 function proxyFetch(targetUrl) { // 必须编码否则 和 会被当作查询参数解析 const encodedUrl encodeURIComponent(targetUrl); return fetch(/proxy/?url${encodedUrl}, { method: GET }); } // 使用示例 async function loadVideo(videoUrl) { try { const response await proxyFetch(videoUrl); if (!response.ok) { throw new Error(HTTP ${response.status}); } const blob await response.blob(); const objectUrl URL.createObjectURL(blob); const video document.querySelector(video); video.src objectUrl; } catch (error) { console.error(Failed:, error); } } // 调用 const cozeVideoUrl https://lf6-bot-platform-tos-sign.coze.cn/bot-studio-bot-platform/bot_files/3850925219778179/video/quicktime/7641920355644571682/7e9889f1-8059-4846-bbc1-2f1fea5ad040.mp4?x-expires1779878095x-signature5mgX3n%2BmKwjzWIEP%2Ffm8xTODlZQ%3D; loadVideo(cozeVideoUrl);